Fix Conversation page flickers
In this page, 3 conversation lists are implemented by the
ConversationListPreferenceController, these lists updates its contents
in updateState(), which is after the preference screen view created.
So when the first time this page is showed, animations of added contents
will be shown.
The improvement is when the first time, update the list in the
onCreate(), which is called before view creation, instead of the
updateState().
And also do the same thing for RecentConversationsPreferenceController.
Also, to reduce latency,
1. Because currently there are duplicated calls in
NoConversationsPreferenceController to check whether conversations are
exists or not, by removing the duplicated calls and reuse the result
from other controllers, the latency could be reduced.
2. Currently, there are seperated api calls, the
mBackend.getConversations(false) in AllConversationsPreferenceController
and the mBackend.getConversations(true) in
PriorityConversationsPreferenceController, use one
mBackend.getConversations(false) in ConversationListSettings to improve,
this does not change the behavior because the result is filtered in
matchesFilter() both before and after.
3. Currently, we sort conversations first then filter them, change to
filter first then sort to reduce latency.
Fix: 215073227
Test: visual check & robo tests
Change-Id: I028a7fabbbf64cf5627e6615372282a36eb784e5
diff --git a/res/layout/conversation_onboarding.xml b/res/layout/conversation_onboarding.xml
index 5d727f6..5cf36cd 100644
--- a/res/layout/conversation_onboarding.xml
+++ b/res/layout/conversation_onboarding.xml
@@ -15,12 +15,10 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/onboarding"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
- android:visibility="gone"
android:orientation="vertical">
<ImageView
diff --git a/src/com/android/settings/notification/app/AllConversationsPreferenceController.java b/src/com/android/settings/notification/app/AllConversationsPreferenceController.java
index f61e167..c863190 100644
--- a/src/com/android/settings/notification/app/AllConversationsPreferenceController.java
+++ b/src/com/android/settings/notification/app/AllConversationsPreferenceController.java
@@ -17,26 +17,18 @@
package com.android.settings.notification.app;
import android.content.Context;
-import android.os.AsyncTask;
import android.service.notification.ConversationChannelWrapper;
import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
import com.android.settings.R;
import com.android.settings.notification.NotificationBackend;
-import java.util.Collections;
-import java.util.List;
-
public class AllConversationsPreferenceController extends ConversationListPreferenceController {
private static final String KEY = "other_conversations";
- private List<ConversationChannelWrapper> mConversations;
-
- public AllConversationsPreferenceController(Context context,
- NotificationBackend backend) {
+ public AllConversationsPreferenceController(Context context, NotificationBackend backend) {
super(context, backend);
}
@@ -46,11 +38,6 @@
}
@Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
Preference getSummaryPreference() {
Preference pref = new Preference(mContext);
pref.setOrder(1);
@@ -63,15 +50,4 @@
boolean matchesFilter(ConversationChannelWrapper conversation) {
return !conversation.getNotificationChannel().isImportantConversation();
}
-
- @Override
- public void updateState(Preference preference) {
- PreferenceCategory pref = (PreferenceCategory) preference;
- // Load conversations
-
- mConversations = mBackend.getConversations(false).getList();
- Collections.sort(mConversations, mConversationComparator);
-
- populateList(mConversations, pref);
- }
}
diff --git a/src/com/android/settings/notification/app/ConversationListPreferenceController.java b/src/com/android/settings/notification/app/ConversationListPreferenceController.java
index 29f0dea..f893df3 100644
--- a/src/com/android/settings/notification/app/ConversationListPreferenceController.java
+++ b/src/com/android/settings/notification/app/ConversationListPreferenceController.java
@@ -25,8 +25,10 @@
import android.service.notification.ConversationChannelWrapper;
import android.text.TextUtils;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
+import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.applications.AppInfoBase;
@@ -38,14 +40,15 @@
import java.text.Collator;
import java.util.Comparator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
public abstract class ConversationListPreferenceController extends AbstractPreferenceController {
private static final String SUMMARY_KEY_SUFFIX = "_summary";
protected final NotificationBackend mBackend;
+ private PreferenceGroup mPreferenceGroup;
- public ConversationListPreferenceController(Context context,
- NotificationBackend backend) {
+ public ConversationListPreferenceController(Context context, NotificationBackend backend) {
super(context);
mBackend = backend;
}
@@ -55,44 +58,55 @@
return true;
}
- protected void populateList(List<ConversationChannelWrapper> conversations,
- PreferenceGroup containerGroup) {
- containerGroup.setVisible(false);
- containerGroup.removeAll();
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreferenceGroup = screen.findPreference(getPreferenceKey());
+ }
+
+ /**
+ * Updates the conversation list.
+ * @return true if this controller has content to display.
+ */
+ boolean updateList(List<ConversationChannelWrapper> conversations) {
+ mPreferenceGroup.setVisible(false);
+ mPreferenceGroup.removeAll();
if (conversations != null) {
- populateConversations(conversations, containerGroup);
+ populateConversations(conversations);
}
- if (containerGroup.getPreferenceCount() != 0) {
+ boolean hasContent = mPreferenceGroup.getPreferenceCount() != 0;
+ if (hasContent) {
Preference summaryPref = getSummaryPreference();
if (summaryPref != null) {
summaryPref.setKey(getPreferenceKey() + SUMMARY_KEY_SUFFIX);
- containerGroup.addPreference(summaryPref);
+ mPreferenceGroup.addPreference(summaryPref);
}
- containerGroup.setVisible(true);
+ mPreferenceGroup.setVisible(true);
}
+ return hasContent;
}
abstract Preference getSummaryPreference();
abstract boolean matchesFilter(ConversationChannelWrapper conversation);
- protected void populateConversations(List<ConversationChannelWrapper> conversations,
- PreferenceGroup containerGroup) {
- int order = 100;
- for (ConversationChannelWrapper conversation : conversations) {
- if (conversation.getNotificationChannel().isDemoted()
- || !matchesFilter(conversation)) {
- continue;
- }
- containerGroup.addPreference(createConversationPref(conversation, order++));
- }
+ @VisibleForTesting
+ void populateConversations(List<ConversationChannelWrapper> conversations) {
+ AtomicInteger order = new AtomicInteger(100);
+ conversations.stream()
+ .filter(conversation -> !conversation.getNotificationChannel().isDemoted()
+ && matchesFilter(conversation))
+ .sorted(mConversationComparator)
+ .map(this::createConversationPref)
+ .forEachOrdered(preference -> {
+ preference.setOrder(order.getAndIncrement());
+ mPreferenceGroup.addPreference(preference);
+ });
}
- protected Preference createConversationPref(final ConversationChannelWrapper conversation,
- int order) {
+ private Preference createConversationPref(final ConversationChannelWrapper conversation) {
AppPreference pref = new AppPreference(mContext);
- pref.setOrder(order);
pref.setTitle(getTitle(conversation));
pref.setSummary(getSummary(conversation));
@@ -141,7 +155,8 @@
.setSourceMetricsCategory(SettingsEnums.NOTIFICATION_CONVERSATION_LIST_SETTINGS);
}
- protected Comparator<ConversationChannelWrapper> mConversationComparator =
+ @VisibleForTesting
+ Comparator<ConversationChannelWrapper> mConversationComparator =
new Comparator<ConversationChannelWrapper>() {
private final Collator sCollator = Collator.getInstance();
@Override
diff --git a/src/com/android/settings/notification/app/ConversationListSettings.java b/src/com/android/settings/notification/app/ConversationListSettings.java
index 83fc072..f2db47d 100644
--- a/src/com/android/settings/notification/app/ConversationListSettings.java
+++ b/src/com/android/settings/notification/app/ConversationListSettings.java
@@ -19,8 +19,9 @@
import android.app.people.IPeopleManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.os.Bundle;
import android.os.ServiceManager;
-import android.util.Log;
+import android.service.notification.ConversationChannelWrapper;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
@@ -32,12 +33,16 @@
public class ConversationListSettings extends DashboardFragment {
private static final String TAG = "ConvoListSettings";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
NotificationBackend mBackend = new NotificationBackend();
IPeopleManager mPs;
protected List<AbstractPreferenceController> mControllers = new ArrayList<>();
+ private NoConversationsPreferenceController mNoConversationsController;
+ private PriorityConversationsPreferenceController mPriorityConversationsController;
+ private AllConversationsPreferenceController mAllConversationsController;
+ private RecentConversationsPreferenceController mRecentConversationsController;
+ private boolean mUpdatedInOnCreate = false;
public ConversationListSettings() {
mPs = IPeopleManager.Stub.asInterface(
@@ -62,10 +67,43 @@
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
- mControllers.add(new NoConversationsPreferenceController(context, mBackend, mPs));
- mControllers.add(new PriorityConversationsPreferenceController(context, mBackend));
- mControllers.add(new AllConversationsPreferenceController(context, mBackend));
- mControllers.add(new RecentConversationsPreferenceController(context, mBackend, mPs));
+ mNoConversationsController = new NoConversationsPreferenceController(context);
+ mControllers.add(mNoConversationsController);
+ mPriorityConversationsController =
+ new PriorityConversationsPreferenceController(context, mBackend);
+ mControllers.add(mPriorityConversationsController);
+ mAllConversationsController = new AllConversationsPreferenceController(context, mBackend);
+ mControllers.add(mAllConversationsController);
+ mRecentConversationsController =
+ new RecentConversationsPreferenceController(context, mBackend, mPs);
+ mControllers.add(mRecentConversationsController);
return new ArrayList<>(mControllers);
}
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ update();
+ mUpdatedInOnCreate = true;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ if (mUpdatedInOnCreate) {
+ mUpdatedInOnCreate = false;
+ } else {
+ update();
+ }
+ }
+
+ private void update() {
+ List<ConversationChannelWrapper> conversationList =
+ mBackend.getConversations(false).getList();
+ boolean hasContent = mPriorityConversationsController.updateList(conversationList)
+ | mAllConversationsController.updateList(conversationList)
+ | mRecentConversationsController.updateList();
+ mNoConversationsController.setAvailable(!hasContent);
+ mNoConversationsController.displayPreference(getPreferenceScreen());
+ }
}
diff --git a/src/com/android/settings/notification/app/NoConversationsPreferenceController.java b/src/com/android/settings/notification/app/NoConversationsPreferenceController.java
index 475d90d..21b8718 100644
--- a/src/com/android/settings/notification/app/NoConversationsPreferenceController.java
+++ b/src/com/android/settings/notification/app/NoConversationsPreferenceController.java
@@ -16,32 +16,18 @@
package com.android.settings.notification.app;
-import android.app.people.IPeopleManager;
import android.content.Context;
-import android.os.AsyncTask;
-import android.os.RemoteException;
-import android.service.notification.ConversationChannelWrapper;
-import android.util.Log;
-import android.view.View;
-import androidx.preference.Preference;
+import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settings.R;
-import com.android.settings.notification.NotificationBackend;
-import com.android.settingslib.widget.LayoutPreference;
+class NoConversationsPreferenceController extends AbstractPreferenceController {
-public class NoConversationsPreferenceController extends ConversationListPreferenceController {
-
- private static String TAG = "NoConversationsPC";
private static final String KEY = "no_conversations";
- private IPeopleManager mPs;
- private int mConversationCount = 0;
+ private boolean mIsAvailable = false;
- public NoConversationsPreferenceController(Context context,
- NotificationBackend backend, IPeopleManager ps) {
- super(context, backend);
- mPs = ps;
+ NoConversationsPreferenceController(Context context) {
+ super(context);
}
@Override
@@ -51,44 +37,10 @@
@Override
public boolean isAvailable() {
- return true;
+ return mIsAvailable;
}
- @Override
- Preference getSummaryPreference() {
- return null;
- }
-
- @Override
- boolean matchesFilter(ConversationChannelWrapper conversation) {
- return false;
- }
-
- @Override
- public void updateState(Preference preference) {
- LayoutPreference pref = (LayoutPreference) preference;
- // Load conversations
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... unused) {
- mConversationCount = mBackend.getConversations(false).getList().size();
- try {
- mConversationCount += mPs.getRecentConversations().getList().size();
- } catch (RemoteException e) {
- Log.w(TAG, "Error calling PS", e);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void unused) {
- if (mContext == null) {
- return;
- }
- pref.findViewById(R.id.onboarding).setVisibility(mConversationCount == 0
- ? View.VISIBLE : View.GONE);
- preference.setVisible(mConversationCount == 0);
- }
- }.execute();
+ void setAvailable(boolean available) {
+ mIsAvailable = available;
}
}
diff --git a/src/com/android/settings/notification/app/PriorityConversationsPreferenceController.java b/src/com/android/settings/notification/app/PriorityConversationsPreferenceController.java
index 3fb605b..18fc917 100644
--- a/src/com/android/settings/notification/app/PriorityConversationsPreferenceController.java
+++ b/src/com/android/settings/notification/app/PriorityConversationsPreferenceController.java
@@ -17,26 +17,19 @@
package com.android.settings.notification.app;
import android.content.Context;
-import android.os.AsyncTask;
import android.service.notification.ConversationChannelWrapper;
import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
import com.android.settings.R;
import com.android.settings.notification.NotificationBackend;
-import java.util.Collections;
-import java.util.List;
-
public class PriorityConversationsPreferenceController extends
ConversationListPreferenceController {
private static final String KEY = "important_conversations";
- private List<ConversationChannelWrapper> mConversations;
- public PriorityConversationsPreferenceController(Context context,
- NotificationBackend backend) {
+ public PriorityConversationsPreferenceController(Context context, NotificationBackend backend) {
super(context, backend);
}
@@ -46,11 +39,6 @@
}
@Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
Preference getSummaryPreference() {
Preference pref = new Preference(mContext);
pref.setOrder(1);
@@ -63,14 +51,4 @@
boolean matchesFilter(ConversationChannelWrapper conversation) {
return conversation.getNotificationChannel().isImportantConversation();
}
-
- @Override
- public void updateState(Preference preference) {
- PreferenceCategory pref = (PreferenceCategory) preference;
- // Load conversations
- mConversations = mBackend.getConversations(true).getList();
- Collections.sort(mConversations, mConversationComparator);
-
- populateList(mConversations, pref);
- }
}
diff --git a/src/com/android/settings/notification/app/RecentConversationsPreferenceController.java b/src/com/android/settings/notification/app/RecentConversationsPreferenceController.java
index 4d8cefe..f5f2e97 100644
--- a/src/com/android/settings/notification/app/RecentConversationsPreferenceController.java
+++ b/src/com/android/settings/notification/app/RecentConversationsPreferenceController.java
@@ -30,9 +30,10 @@
import android.util.Slog;
import android.widget.Button;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceGroup;
+import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.applications.AppInfoBase;
@@ -45,18 +46,20 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
public class RecentConversationsPreferenceController extends AbstractPreferenceController {
private static final String TAG = "RecentConversationsPC";
private static final String KEY = "recent_conversations";
private static final String CLEAR_ALL_KEY_SUFFIX = "_clear_all";
- private List<ConversationChannel> mConversations;
private final IPeopleManager mPs;
private final NotificationBackend mBackend;
+ private PreferenceGroup mPreferenceGroup;
- public RecentConversationsPreferenceController(Context context, NotificationBackend backend,
- IPeopleManager ps) {
+ public RecentConversationsPreferenceController(
+ Context context, NotificationBackend backend, IPeopleManager ps) {
super(context);
mBackend = backend;
mPs = ps;
@@ -103,63 +106,69 @@
}
@Override
- public void updateState(Preference preference) {
- PreferenceCategory pref = (PreferenceCategory) preference;
- // Load conversations
- try {
- mConversations = mPs.getRecentConversations().getList();
- } catch (RemoteException e) {
- Slog.w(TAG, "Could get recents", e);
- }
- Collections.sort(mConversations, mConversationComparator);
-
- populateList(mConversations, pref);
-
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreferenceGroup = screen.findPreference(getPreferenceKey());
}
- protected void populateList(List<ConversationChannel> conversations,
- PreferenceGroup containerGroup) {
- containerGroup.removeAll();
+ /**
+ * Updates the conversation list.
+ *
+ * @return true if this controller has content to display.
+ */
+ boolean updateList() {
+ // Load conversations
+ List<ConversationChannel> conversations = Collections.emptyList();
+ try {
+ conversations = mPs.getRecentConversations().getList();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Could not get recent conversations", e);
+ }
+
+ return populateList(conversations);
+ }
+
+ @VisibleForTesting
+ boolean populateList(List<ConversationChannel> conversations) {
+ mPreferenceGroup.removeAll();
boolean hasClearable = false;
if (conversations != null) {
- hasClearable = populateConversations(conversations, containerGroup);
+ hasClearable = populateConversations(conversations);
}
- if (containerGroup.getPreferenceCount() == 0) {
- containerGroup.setVisible(false);
- } else {
- containerGroup.setVisible(true);
- if (hasClearable) {
- Preference clearAll = getClearAll(containerGroup);
- if (clearAll != null) {
- containerGroup.addPreference(clearAll);
- }
+ boolean hashContent = mPreferenceGroup.getPreferenceCount() != 0;
+ mPreferenceGroup.setVisible(hashContent);
+ if (hashContent && hasClearable) {
+ Preference clearAll = getClearAll(mPreferenceGroup);
+ if (clearAll != null) {
+ mPreferenceGroup.addPreference(clearAll);
}
}
+ return hashContent;
}
- protected boolean populateConversations(List<ConversationChannel> conversations,
- PreferenceGroup containerGroup) {
- int order = 100;
- boolean hasClearable = false;
- for (ConversationChannel conversation : conversations) {
- if (conversation.getNotificationChannel().getImportance() == IMPORTANCE_NONE
- || (conversation.getNotificationChannelGroup() != null
- && conversation.getNotificationChannelGroup().isBlocked())) {
- continue;
- }
- RecentConversationPreference pref =
- createConversationPref(containerGroup, conversation, order++);
- containerGroup.addPreference(pref);
- if (pref.hasClearListener()) {
- hasClearable = true;
- }
- }
- return hasClearable;
+ protected boolean populateConversations(List<ConversationChannel> conversations) {
+ AtomicInteger order = new AtomicInteger(100);
+ AtomicBoolean hasClearable = new AtomicBoolean(false);
+ conversations.stream()
+ .filter(conversation ->
+ conversation.getNotificationChannel().getImportance() != IMPORTANCE_NONE
+ && (conversation.getNotificationChannelGroup() == null
+ || !conversation.getNotificationChannelGroup().isBlocked()))
+ .sorted(mConversationComparator)
+ .map(this::createConversationPref)
+ .forEachOrdered(pref -> {
+ pref.setOrder(order.getAndIncrement());
+ mPreferenceGroup.addPreference(pref);
+ if (pref.hasClearListener()) {
+ hasClearable.set(true);
+ }
+ });
+ return hasClearable.get();
}
- protected RecentConversationPreference createConversationPref(PreferenceGroup parent,
- final ConversationChannel conversation, int order) {
+ protected RecentConversationPreference createConversationPref(
+ final ConversationChannel conversation) {
final String pkg = conversation.getShortcutInfo().getPackage();
final int uid = conversation.getUid();
final String conversationId = conversation.getShortcutInfo().getId();
@@ -171,13 +180,12 @@
mPs.removeRecentConversation(pkg, UserHandle.getUserId(uid), conversationId);
pref.getClearView().announceForAccessibility(
mContext.getString(R.string.recent_convo_removed));
- parent.removePreference(pref);
+ mPreferenceGroup.removePreference(pref);
} catch (RemoteException e) {
Slog.w(TAG, "Could not clear recent", e);
}
});
}
- pref.setOrder(order);
pref.setTitle(getTitle(conversation));
pref.setSummary(getSummary(conversation));
@@ -230,9 +238,11 @@
.setSourceMetricsCategory(SettingsEnums.NOTIFICATION_CONVERSATION_LIST_SETTINGS);
}
- protected Comparator<ConversationChannel> mConversationComparator =
+ @VisibleForTesting
+ Comparator<ConversationChannel> mConversationComparator =
new Comparator<ConversationChannel>() {
private final Collator sCollator = Collator.getInstance();
+
@Override
public int compare(ConversationChannel o1, ConversationChannel o2) {
int labelComparison = 0;
diff --git a/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
index 8113f22..aaa2f24 100644
--- a/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
@@ -21,7 +21,6 @@
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
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;
@@ -35,47 +34,49 @@
import android.service.notification.ConversationChannelWrapper;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
-import android.text.style.BulletSpan;
-import android.text.style.QuoteSpan;
import android.text.style.SubscriptSpan;
-import android.text.style.UnderlineSpan;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.notification.NotificationBackend;
+import com.google.common.collect.ImmutableList;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowApplication;
-
-import java.util.ArrayList;
@RunWith(RobolectricTestRunner.class)
public class ConversationListPreferenceControllerTest {
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
+ private final Context mContext = ApplicationProvider.getApplicationContext();
@Mock
private NotificationBackend mBackend;
+ @Spy
+ private PreferenceGroup mPreferenceGroup = new PreferenceCategory(mContext);
private TestPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- ShadowApplication shadowApplication = ShadowApplication.getInstance();
- mContext = RuntimeEnvironment.application;
mController = new TestPreferenceController(mContext, mBackend);
+
+ PreferenceManager preferenceManager = new PreferenceManager(mContext);
+ PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext);
+ mPreferenceGroup.setKey(mController.getPreferenceKey());
+ preferenceScreen.addPreference(mPreferenceGroup);
+ mController.displayPreference(preferenceScreen);
}
@Test
@@ -84,39 +85,30 @@
}
@Test
- public void testPopulateList_hideIfNoConversations() {
- PreferenceCategory outerContainer = mock(PreferenceCategory.class);
+ public void testUpdateList_hideIfNoConversations() {
+ boolean hasContent = mController.updateList(ImmutableList.of());
- mController.populateList(new ArrayList<>(), outerContainer);
-
- verify(outerContainer).setVisible(false);
- verify(outerContainer, never()).addPreference(any());
+ assertThat(hasContent).isFalse();
+ verify(mPreferenceGroup).setVisible(false);
+ verify(mPreferenceGroup, never()).addPreference(any());
}
@Test
- public void testPopulateList_validConversations() {
- final PreferenceManager preferenceManager = new PreferenceManager(mContext);
- PreferenceScreen ps = preferenceManager.createPreferenceScreen(mContext);
- PreferenceCategory outerContainer = spy(new PreferenceCategory(mContext));
- ps.addPreference(outerContainer);
-
+ public void testUpdateList_validConversations() {
ConversationChannelWrapper ccw = new ConversationChannelWrapper();
ccw.setNotificationChannel(mock(NotificationChannel.class));
ccw.setPkg("pkg");
ccw.setUid(1);
ccw.setShortcutInfo(mock(ShortcutInfo.class));
- ArrayList<ConversationChannelWrapper> list = new ArrayList<>();
- list.add(ccw);
+ boolean hasContent = mController.updateList(ImmutableList.of(ccw));
- mController.populateList(list, outerContainer);
- verify(outerContainer, times(1)).addPreference(any());
+ assertThat(hasContent).isTrue();
+ verify(mPreferenceGroup, times(1)).addPreference(any());
}
@Test
public void populateConversations() {
- PreferenceCategory container = mock(PreferenceCategory.class);
-
ConversationChannelWrapper ccw = new ConversationChannelWrapper();
ccw.setNotificationChannel(mock(NotificationChannel.class));
ccw.setPkg("pkg");
@@ -131,13 +123,9 @@
ccwDemoted.setUid(1);
ccwDemoted.setShortcutInfo(mock(ShortcutInfo.class));
- ArrayList<ConversationChannelWrapper> list = new ArrayList<>();
- list.add(ccw);
- list.add(ccwDemoted);
+ mController.populateConversations(ImmutableList.of(ccw, ccwDemoted));
- mController.populateConversations(list, container);
-
- verify(container, times(1)).addPreference(any());
+ verify(mPreferenceGroup, times(1)).addPreference(any());
}
@Test
@@ -240,7 +228,8 @@
assertThat(mController.mConversationComparator.compare(one, two)).isLessThan(0);
}
- private final class TestPreferenceController extends ConversationListPreferenceController {
+ private static final class TestPreferenceController extends
+ ConversationListPreferenceController {
private TestPreferenceController(Context context, NotificationBackend backend) {
super(context, backend);
diff --git a/tests/robotests/src/com/android/settings/notification/app/RecentConversationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/RecentConversationsPreferenceControllerTest.java
index 1688d63..3c0a0f3 100644
--- a/tests/robotests/src/com/android/settings/notification/app/RecentConversationsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/RecentConversationsPreferenceControllerTest.java
@@ -37,9 +37,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.text.SpannedString;
-import android.view.LayoutInflater;
import android.view.View;
-import android.widget.LinearLayout;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
@@ -47,42 +45,46 @@
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceViewHolder;
+import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.widget.LayoutPreference;
+import com.google.common.collect.ImmutableList;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowApplication;
-
-import java.util.ArrayList;
@RunWith(RobolectricTestRunner.class)
public class RecentConversationsPreferenceControllerTest {
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
+ private final Context mContext = ApplicationProvider.getApplicationContext();
@Mock
private NotificationBackend mBackend;
@Mock
private IPeopleManager mPs;
+ @Spy
+ private PreferenceGroup mPreferenceGroup = new PreferenceCategory(mContext);
private RecentConversationsPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- ShadowApplication shadowApplication = ShadowApplication.getInstance();
- mContext = RuntimeEnvironment.application;
mController = new RecentConversationsPreferenceController(mContext, mBackend, mPs);
+
+ PreferenceManager preferenceManager = new PreferenceManager(mContext);
+ PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext);
+ mPreferenceGroup.setKey(mController.getPreferenceKey());
+ preferenceScreen.addPreference(mPreferenceGroup);
+ mController.displayPreference(preferenceScreen);
}
@Test
@@ -92,38 +94,29 @@
@Test
public void testPopulateList_hideIfNoConversations() {
- PreferenceCategory outerContainer = mock(PreferenceCategory.class);
+ boolean hasContent = mController.populateList(ImmutableList.of());
- mController.populateList(new ArrayList<>(), outerContainer);
-
- verify(outerContainer).setVisible(false);
- verify(outerContainer, never()).addPreference(any());
+ assertThat(hasContent).isFalse();
+ verify(mPreferenceGroup).setVisible(false);
+ verify(mPreferenceGroup, never()).addPreference(any());
}
@Test
public void testPopulateList_validConversations() {
- final PreferenceManager preferenceManager = new PreferenceManager(mContext);
- PreferenceScreen ps = preferenceManager.createPreferenceScreen(mContext);
- PreferenceCategory outerContainer = spy(new PreferenceCategory(mContext));
- ps.addPreference(outerContainer);
-
ConversationChannel ccw = new ConversationChannel(mock(ShortcutInfo.class), 6,
new NotificationChannel("hi", "hi", 4),
new NotificationChannelGroup("hi", "hi"), 7,
false);
- ArrayList<ConversationChannel> list = new ArrayList<>();
- list.add(ccw);
+ boolean hasContent = mController.populateList(ImmutableList.of(ccw));
- mController.populateList(list, outerContainer);
+ assertThat(hasContent).isTrue();
// one for the preference, one for the button ro clear all
- verify(outerContainer, times(2)).addPreference(any());
+ verify(mPreferenceGroup, times(2)).addPreference(any());
}
@Test
public void populateConversations_blocked() {
- PreferenceCategory container = mock(PreferenceCategory.class);
-
ConversationChannel ccw = new ConversationChannel(mock(ShortcutInfo.class), 6,
new NotificationChannel("hi", "hi", 4),
new NotificationChannelGroup("hi", "hi"), 7,
@@ -141,14 +134,10 @@
blockedGroup, 7,
false);
- ArrayList<ConversationChannel> list = new ArrayList<>();
- list.add(ccw);
- list.add(ccw2);
- list.add(ccw3);
+ boolean hasContent = mController.populateConversations(ImmutableList.of(ccw, ccw2, ccw3));
- mController.populateConversations(list, container);
-
- verify(container, times(1)).addPreference(any());
+ assertThat(hasContent).isTrue();
+ verify(mPreferenceGroup, times(1)).addPreference(any());
}
@Test
@@ -223,8 +212,7 @@
new NotificationChannelGroup("hi", "group"), 7,
true);
- Preference pref = mController.createConversationPref(new PreferenceCategory(mContext),
- ccw, 100);
+ Preference pref = mController.createConversationPref(ccw);
try {
pref.performClick();
} catch (RuntimeException e) {
@@ -244,9 +232,7 @@
new NotificationChannelGroup("hi", "group"), 7,
false);
- RecentConversationPreference pref =
- (RecentConversationPreference) mController.createConversationPref(
- new PreferenceCategory(mContext), ccw, 100);
+ RecentConversationPreference pref = mController.createConversationPref(ccw);
final View view = View.inflate(mContext, pref.getLayoutResource(), null);
PreferenceViewHolder holder = spy(PreferenceViewHolder.createInstanceForTests(view));
View delete = View.inflate(mContext, pref.getSecondTargetResId(), null);
@@ -274,34 +260,28 @@
new NotificationChannelGroup("hi", "group"), 7,
true);
- PreferenceCategory group = new PreferenceCategory(mContext);
- PreferenceScreen screen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
- screen.addPreference(group);
-
- RecentConversationPreference pref = mController.createConversationPref(
- new PreferenceCategory(mContext), ccw, 100);
+ RecentConversationPreference pref = mController.createConversationPref(ccw);
final View view = View.inflate(mContext, pref.getLayoutResource(), null);
PreferenceViewHolder holder = spy(PreferenceViewHolder.createInstanceForTests(view));
View delete = View.inflate(mContext, pref.getSecondTargetResId(), null);
when(holder.findViewById(pref.getClearId())).thenReturn(delete);
- group.addPreference(pref);
+ mPreferenceGroup.addPreference(pref);
- RecentConversationPreference pref2 = mController.createConversationPref(
- new PreferenceCategory(mContext), ccw2, 100);
+ RecentConversationPreference pref2 = mController.createConversationPref(ccw2);
final View view2 = View.inflate(mContext, pref2.getLayoutResource(), null);
PreferenceViewHolder holder2 = spy(PreferenceViewHolder.createInstanceForTests(view2));
View delete2 = View.inflate(mContext, pref2.getSecondTargetResId(), null);
when(holder2.findViewById(pref.getClearId())).thenReturn(delete2);
- group.addPreference(pref2);
+ mPreferenceGroup.addPreference(pref2);
- LayoutPreference clearAll = mController.getClearAll(group);
- group.addPreference(clearAll);
+ LayoutPreference clearAll = mController.getClearAll(mPreferenceGroup);
+ mPreferenceGroup.addPreference(clearAll);
clearAll.findViewById(R.id.conversation_settings_clear_recents).performClick();
verify(mPs).removeAllRecentConversations();
- assertThat((Preference) group.findPreference("hi:person")).isNull();
- assertThat((Preference) group.findPreference("bye:person")).isNotNull();
+ assertThat((Preference) mPreferenceGroup.findPreference("hi:person")).isNull();
+ assertThat((Preference) mPreferenceGroup.findPreference("bye:person")).isNotNull();
}
@Test
@@ -314,30 +294,23 @@
new NotificationChannelGroup("hi", "group"), 7,
true);
- RecentConversationPreference pref =
- (RecentConversationPreference) mController.createConversationPref(
- new PreferenceCategory(mContext), ccw, 100);
+ RecentConversationPreference pref = mController.createConversationPref(ccw);
+
assertThat(pref.hasClearListener()).isFalse();
}
@Test
public void testPopulateList_onlyNonremoveableConversations() {
- final PreferenceManager preferenceManager = new PreferenceManager(mContext);
- PreferenceScreen ps = preferenceManager.createPreferenceScreen(mContext);
- PreferenceCategory outerContainer = spy(new PreferenceCategory(mContext));
- ps.addPreference(outerContainer);
-
ConversationChannel ccw = new ConversationChannel(mock(ShortcutInfo.class), 6,
new NotificationChannel("hi", "hi", 4),
new NotificationChannelGroup("hi", "hi"), 7,
true /* hasactivenotifs */);
- ArrayList<ConversationChannel> list = new ArrayList<>();
- list.add(ccw);
+ boolean hasContent = mController.populateList(ImmutableList.of(ccw));
- mController.populateList(list, outerContainer);
+ assertThat(hasContent).isTrue();
// one for the preference, none for 'clear all'
- verify(outerContainer, times(1)).addPreference(any());
+ verify(mPreferenceGroup, times(1)).addPreference(any());
}
@Test