diff --git a/res/layout/conversation_onboarding.xml b/res/layout/conversation_onboarding.xml index 5d727f6b8f9..5cf36cdfffa 100644 --- a/res/layout/conversation_onboarding.xml +++ b/res/layout/conversation_onboarding.xml @@ -15,12 +15,10 @@ --> mConversations; - - public AllConversationsPreferenceController(Context context, - NotificationBackend backend) { + public AllConversationsPreferenceController(Context context, NotificationBackend backend) { super(context, backend); } @@ -45,11 +37,6 @@ public class AllConversationsPreferenceController extends ConversationListPrefer return KEY; } - @Override - public boolean isAvailable() { - return true; - } - @Override Preference getSummaryPreference() { Preference pref = new Preference(mContext); @@ -63,15 +50,4 @@ public class AllConversationsPreferenceController extends ConversationListPrefer 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 29f0dea6991..f893df305e8 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.provider.Settings; 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 com.android.settingslib.widget.AppPreference; 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 @@ public abstract class ConversationListPreferenceController extends AbstractPrefe return true; } - protected void populateList(List 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 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 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 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 @@ public abstract class ConversationListPreferenceController extends AbstractPrefe .setSourceMetricsCategory(SettingsEnums.NOTIFICATION_CONVERSATION_LIST_SETTINGS); } - protected Comparator mConversationComparator = + @VisibleForTesting + Comparator mConversationComparator = new Comparator() { 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 83fc072adbb..f2db47daffe 100644 --- a/src/com/android/settings/notification/app/ConversationListSettings.java +++ b/src/com/android/settings/notification/app/ConversationListSettings.java @@ -19,8 +19,9 @@ package com.android.settings.notification.app; 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 @@ import java.util.List; 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 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 @@ public class ConversationListSettings extends DashboardFragment { @Override protected List 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 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 475d90d50f3..21b87188eb6 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 @@ public class NoConversationsPreferenceController extends ConversationListPrefere @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() { - @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 3fb605bd2fe..18fc9178510 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 mConversations; - public PriorityConversationsPreferenceController(Context context, - NotificationBackend backend) { + public PriorityConversationsPreferenceController(Context context, NotificationBackend backend) { super(context, backend); } @@ -45,11 +38,6 @@ public class PriorityConversationsPreferenceController extends return KEY; } - @Override - public boolean isAvailable() { - return true; - } - @Override Preference getSummaryPreference() { Preference pref = new Preference(mContext); @@ -63,14 +51,4 @@ public class PriorityConversationsPreferenceController extends 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 4d8cefef5e8..f5f2e97090b 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.provider.Settings; 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.text.Collator; 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 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 @@ public class RecentConversationsPreferenceController extends AbstractPreferenceC } @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 conversations, - PreferenceGroup containerGroup) { - containerGroup.removeAll(); + /** + * Updates the conversation list. + * + * @return true if this controller has content to display. + */ + boolean updateList() { + // Load conversations + List 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 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 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 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 @@ public class RecentConversationsPreferenceController extends AbstractPreferenceC 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 @@ public class RecentConversationsPreferenceController extends AbstractPreferenceC .setSourceMetricsCategory(SettingsEnums.NOTIFICATION_CONVERSATION_LIST_SETTINGS); } - protected Comparator mConversationComparator = + @VisibleForTesting + Comparator mConversationComparator = new Comparator() { 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 8113f22826e..aaa2f24f091 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 com.google.common.truth.Truth.assertThat; 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.provider.Settings; 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 @@ public class ConversationListPreferenceControllerTest { } @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 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 @@ public class ConversationListPreferenceControllerTest { ccwDemoted.setUid(1); ccwDemoted.setShortcutInfo(mock(ShortcutInfo.class)); - ArrayList 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 @@ public class ConversationListPreferenceControllerTest { 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 1688d63ec52..3c0a0f33349 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.Bundle; 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.PreferenceGroup; 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 @@ public class RecentConversationsPreferenceControllerTest { @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 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 @@ public class RecentConversationsPreferenceControllerTest { blockedGroup, 7, false); - ArrayList 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 @@ public class RecentConversationsPreferenceControllerTest { 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 @@ public class RecentConversationsPreferenceControllerTest { 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 @@ public class RecentConversationsPreferenceControllerTest { 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 @@ public class RecentConversationsPreferenceControllerTest { 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 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