From d2f4d2171b3f8c42dc69d6636e09542dce9ae7bf Mon Sep 17 00:00:00 2001 From: Joshua Trask Date: Tue, 26 Sep 2023 17:27:53 +0000 Subject: Begin extracting `emptystate` module. This CL just contains the initial code-moves to group relevant classes (including some inner classes/interfaces that are being pulled out of `MultiProfilePagerAdapter`), without any other anticipated fixes or reorganization. This corresponds to snapshots 1-3 of the prototype ag/24516421 (to be followed with the other work that was started in that CL). Bug: 302311217 Test: IntentResolverUnitTests, CtsSharesheetDeviceTest Change-Id: If82a761193f6ff0605c5a46c106f7c95699350c0 --- .../ChooserActivityOverrideData.java | 2 +- .../intentresolver/ChooserWrapperActivity.java | 2 +- .../intentresolver/MultiProfilePagerAdapterTest.kt | 15 ++-- .../intentresolver/ResolverWrapperActivity.java | 2 +- .../emptystate/CompositeEmptyStateProviderTest.kt | 65 +++++++++++++++++ .../emptystate/CrossProfileIntentsCheckerTest.kt | 84 ++++++++++++++++++++++ 6 files changed, 160 insertions(+), 10 deletions(-) create mode 100644 java/tests/src/com/android/intentresolver/emptystate/CompositeEmptyStateProviderTest.kt create mode 100644 java/tests/src/com/android/intentresolver/emptystate/CrossProfileIntentsCheckerTest.kt (limited to 'java/tests') diff --git a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java index 3bf144dd..3ee80c14 100644 --- a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java +++ b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java @@ -26,9 +26,9 @@ import android.content.res.Resources; import android.database.Cursor; import android.os.UserHandle; -import com.android.intentresolver.MultiProfilePagerAdapter.CrossProfileIntentsChecker; import com.android.intentresolver.chooser.TargetInfo; import com.android.intentresolver.contentpreview.ImageLoader; +import com.android.intentresolver.emptystate.CrossProfileIntentsChecker; import com.android.intentresolver.shortcuts.ShortcutLoader; import java.util.function.Consumer; diff --git a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java index 64c4a50a..c9f47a33 100644 --- a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java +++ b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java @@ -34,9 +34,9 @@ import android.os.UserHandle; import androidx.lifecycle.ViewModelProvider; -import com.android.intentresolver.MultiProfilePagerAdapter.CrossProfileIntentsChecker; import com.android.intentresolver.chooser.DisplayResolveInfo; import com.android.intentresolver.chooser.TargetInfo; +import com.android.intentresolver.emptystate.CrossProfileIntentsChecker; import com.android.intentresolver.grid.ChooserGridAdapter; import com.android.intentresolver.icons.TargetDataLoader; import com.android.intentresolver.shortcuts.ShortcutLoader; diff --git a/java/tests/src/com/android/intentresolver/MultiProfilePagerAdapterTest.kt b/java/tests/src/com/android/intentresolver/MultiProfilePagerAdapterTest.kt index dcf53cea..56034f0a 100644 --- a/java/tests/src/com/android/intentresolver/MultiProfilePagerAdapterTest.kt +++ b/java/tests/src/com/android/intentresolver/MultiProfilePagerAdapterTest.kt @@ -22,6 +22,7 @@ import android.widget.ListView import androidx.test.platform.app.InstrumentationRegistry import com.android.intentresolver.MultiProfilePagerAdapter.PROFILE_PERSONAL import com.android.intentresolver.MultiProfilePagerAdapter.PROFILE_WORK +import com.android.intentresolver.emptystate.EmptyStateProvider import com.google.common.collect.ImmutableList import com.google.common.truth.Truth.assertThat import java.util.Optional @@ -46,7 +47,7 @@ class MultiProfilePagerAdapterTest { listView.setAdapter(bindAdapter) }, ImmutableList.of(personalListAdapter), - object : MultiProfilePagerAdapter.EmptyStateProvider {}, + object : EmptyStateProvider {}, { false }, PROFILE_PERSONAL, null, @@ -80,7 +81,7 @@ class MultiProfilePagerAdapterTest { listView.setAdapter(bindAdapter) }, ImmutableList.of(personalListAdapter, workListAdapter), - object : MultiProfilePagerAdapter.EmptyStateProvider {}, + object : EmptyStateProvider {}, { false }, PROFILE_PERSONAL, WORK_USER_HANDLE, // TODO: why does this test pass even if this is null? @@ -119,7 +120,7 @@ class MultiProfilePagerAdapterTest { listView.setAdapter(bindAdapter) }, ImmutableList.of(personalListAdapter, workListAdapter), - object : MultiProfilePagerAdapter.EmptyStateProvider {}, + object : EmptyStateProvider {}, { false }, PROFILE_WORK, // <-- This test specifically requests we start on work profile. WORK_USER_HANDLE, // TODO: why does this test pass even if this is null? @@ -159,7 +160,7 @@ class MultiProfilePagerAdapterTest { listView.setAdapter(bindAdapter) }, ImmutableList.of(), - object : MultiProfilePagerAdapter.EmptyStateProvider {}, + object : EmptyStateProvider {}, { false }, PROFILE_PERSONAL, null, @@ -187,7 +188,7 @@ class MultiProfilePagerAdapterTest { listView.setAdapter(bindAdapter) }, ImmutableList.of(), - object : MultiProfilePagerAdapter.EmptyStateProvider {}, + object : EmptyStateProvider {}, { false }, PROFILE_PERSONAL, null, @@ -221,7 +222,7 @@ class MultiProfilePagerAdapterTest { listView.setAdapter(bindAdapter) }, ImmutableList.of(personalListAdapter, workListAdapter), - object : MultiProfilePagerAdapter.EmptyStateProvider {}, + object : EmptyStateProvider {}, { true }, // <-- Work mode is quiet. PROFILE_WORK, WORK_USER_HANDLE, @@ -255,7 +256,7 @@ class MultiProfilePagerAdapterTest { listView.setAdapter(bindAdapter) }, ImmutableList.of(personalListAdapter, workListAdapter), - object : MultiProfilePagerAdapter.EmptyStateProvider {}, + object : EmptyStateProvider {}, { false }, // <-- Work mode is not quiet. PROFILE_WORK, WORK_USER_HANDLE, diff --git a/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java b/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java index d4bd123a..fbcfcd35 100644 --- a/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java +++ b/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java @@ -34,10 +34,10 @@ import android.util.Pair; import androidx.annotation.NonNull; import androidx.test.espresso.idling.CountingIdlingResource; -import com.android.intentresolver.MultiProfilePagerAdapter.CrossProfileIntentsChecker; import com.android.intentresolver.chooser.DisplayResolveInfo; import com.android.intentresolver.chooser.SelectableTargetInfo; import com.android.intentresolver.chooser.TargetInfo; +import com.android.intentresolver.emptystate.CrossProfileIntentsChecker; import com.android.intentresolver.icons.TargetDataLoader; import java.util.List; diff --git a/java/tests/src/com/android/intentresolver/emptystate/CompositeEmptyStateProviderTest.kt b/java/tests/src/com/android/intentresolver/emptystate/CompositeEmptyStateProviderTest.kt new file mode 100644 index 00000000..4c05dfb1 --- /dev/null +++ b/java/tests/src/com/android/intentresolver/emptystate/CompositeEmptyStateProviderTest.kt @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 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.intentresolver.emptystate + +import com.android.intentresolver.ResolverListAdapter +import com.android.intentresolver.mock +import com.google.common.truth.Truth.assertThat +import org.junit.Test + +class CompositeEmptyStateProviderTest { + val listAdapter = mock() + + val emptyState1 = object : EmptyState {} + val emptyState2 = object : EmptyState {} + + val positiveEmptyStateProvider1 = + object : EmptyStateProvider { + override fun getEmptyState(listAdapter: ResolverListAdapter) = emptyState1 + } + val positiveEmptyStateProvider2 = + object : EmptyStateProvider { + override fun getEmptyState(listAdapter: ResolverListAdapter) = emptyState2 + } + val nullEmptyStateProvider = + object : EmptyStateProvider { + override fun getEmptyState(listAdapter: ResolverListAdapter) = null + } + + @Test + fun testComposedProvider_returnsFirstEmptyStateInOrder() { + val provider = + CompositeEmptyStateProvider( + nullEmptyStateProvider, + positiveEmptyStateProvider1, + positiveEmptyStateProvider2 + ) + assertThat(provider.getEmptyState(listAdapter)).isSameInstanceAs(emptyState1) + } + + @Test + fun testComposedProvider_allProvidersReturnNull_composedResultIsNull() { + val provider = CompositeEmptyStateProvider(nullEmptyStateProvider) + assertThat(provider.getEmptyState(listAdapter)).isNull() + } + + @Test + fun testComposedProvider_noEmptyStateIfNoDelegateProviders() { + val provider = CompositeEmptyStateProvider() + assertThat(provider.getEmptyState(listAdapter)).isNull() + } +} diff --git a/java/tests/src/com/android/intentresolver/emptystate/CrossProfileIntentsCheckerTest.kt b/java/tests/src/com/android/intentresolver/emptystate/CrossProfileIntentsCheckerTest.kt new file mode 100644 index 00000000..2bcddf59 --- /dev/null +++ b/java/tests/src/com/android/intentresolver/emptystate/CrossProfileIntentsCheckerTest.kt @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2023 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.intentresolver.emptystate + +import android.content.ContentResolver +import android.content.Intent +import android.content.pm.IPackageManager +import com.android.intentresolver.mock +import com.android.intentresolver.whenever +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.mockito.Mockito.any +import org.mockito.Mockito.anyInt +import org.mockito.Mockito.eq +import org.mockito.Mockito.nullable + +class CrossProfileIntentsCheckerTest { + private val PERSONAL_USER_ID = 10 + private val WORK_USER_ID = 20 + + private val contentResolver = mock() + + @Test + fun testChecker_hasCrossProfileIntents() { + val packageManager = + mock { + whenever( + canForwardTo( + any(Intent::class.java), + nullable(String::class.java), + eq(PERSONAL_USER_ID), + eq(WORK_USER_ID) + ) + ) + .thenReturn(true) + } + val checker = CrossProfileIntentsChecker(contentResolver, packageManager) + val intents = listOf(Intent()) + assertThat(checker.hasCrossProfileIntents(intents, PERSONAL_USER_ID, WORK_USER_ID)).isTrue() + } + + @Test + fun testChecker_noCrossProfileIntents() { + val packageManager = + mock { + whenever( + canForwardTo( + any(Intent::class.java), + nullable(String::class.java), + anyInt(), + anyInt() + ) + ) + .thenReturn(false) + } + val checker = CrossProfileIntentsChecker(contentResolver, packageManager) + val intents = listOf(Intent()) + assertThat(checker.hasCrossProfileIntents(intents, PERSONAL_USER_ID, WORK_USER_ID)) + .isFalse() + } + + @Test + fun testChecker_noIntents() { + val packageManager = mock() + val checker = CrossProfileIntentsChecker(contentResolver, packageManager) + val intents = listOf() + assertThat(checker.hasCrossProfileIntents(intents, PERSONAL_USER_ID, WORK_USER_ID)) + .isFalse() + } +} -- cgit v1.2.3-59-g8ed1b