diff options
| author | 2023-07-20 14:06:27 -0400 | |
|---|---|---|
| committer | 2023-08-08 16:39:46 +0000 | |
| commit | 35a34bcaf236597703208cf0472cb268b42abb1c (patch) | |
| tree | a9e27ad3b38d606301ded87bdaeb7fd234706ba3 /java/tests | |
| parent | 5b05c285bc00a34f847037dfe176b6f478eb768d (diff) | |
Adds Dagger support for ViewModel scope
Dependencies may now be bound to ViewModelScope which survives
across Activity configuration restarts. ChooserViewModel is
available in ChooserActivity. ViewModel components should
be provided by ViewModelComponent to wire up the core parts
of the app.
A @ViewModel CoroutineScope is also available to inject from
within ViewModelScope.
* Injects [Resolver|Chooser](Wrapper)Activity in tests
* Injects Intent args (Bundle) into ViewModel
* Injects Referrer (Uri) into ViewModel
Adjusts module structure slightly to accomodate the current
state. Further restructuring will be done to simplify the
test modules & components required.
Test: atest IntentResolverUnitTests
Change-Id: Ia249cf07796a9993f2cd021930c52faadb046ca8
Diffstat (limited to 'java/tests')
12 files changed, 204 insertions, 31 deletions
diff --git a/java/tests/Android.bp b/java/tests/Android.bp index c381d0a8..bb287eb2 100644 --- a/java/tests/Android.bp +++ b/java/tests/Android.bp @@ -19,18 +19,21 @@ android_test { static_libs: [ "IntentResolver-core", - "androidx.test.rules", + "androidx.test.core", "androidx.test.ext.junit", + "androidx.test.ext.truth", "androidx.test.espresso.contrib", - "mockito-target-minus-junit4", "androidx.test.espresso.core", + "androidx.test.rules", "androidx.lifecycle_lifecycle-common-java8", "androidx.lifecycle_lifecycle-extensions", "androidx.lifecycle_lifecycle-runtime-ktx", - "truth-prebuilt", - "testables", "kotlinx_coroutines_test", + "mockito-target-minus-junit4", + "testables", + "truth-prebuilt", ], + plugins: ["dagger2-compiler"], test_suites: ["general-tests"], sdk_version: "core_platform", compile_multilib: "both", diff --git a/java/tests/AndroidManifest.xml b/java/tests/AndroidManifest.xml index b397db5f..9f8dd41c 100644 --- a/java/tests/AndroidManifest.xml +++ b/java/tests/AndroidManifest.xml @@ -27,8 +27,9 @@ <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" /> <application - tools:replace="android:name" - android:name="com.android.intentresolver.TestApplication" > + android:name="com.android.intentresolver.TestApplication" + tools:replace="android:appComponentFactory" + android:appComponentFactory="com.android.intentresolver.dagger.InjectedAppComponentFactory"> <uses-library android:name="android.test.runner" /> <activity android:name="com.android.intentresolver.ChooserWrapperActivity" /> <activity android:name="com.android.intentresolver.ResolverWrapperActivity" /> diff --git a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java index 8608cf72..49305a6c 100644 --- a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java +++ b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java @@ -37,6 +37,7 @@ import androidx.lifecycle.ViewModelProvider; import com.android.intentresolver.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; import com.android.intentresolver.chooser.DisplayResolveInfo; import com.android.intentresolver.chooser.TargetInfo; +import com.android.intentresolver.dagger.TestViewModelComponent; import com.android.intentresolver.flags.FeatureFlagRepository; import com.android.intentresolver.grid.ChooserGridAdapter; import com.android.intentresolver.icons.TargetDataLoader; @@ -47,6 +48,8 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.util.List; import java.util.function.Consumer; +import javax.inject.Inject; + /** * Simple wrapper around chooser activity to be able to initiate it under test. For more * information, see {@code com.android.internal.app.ChooserWrapperActivity}. @@ -56,6 +59,11 @@ public class ChooserWrapperActivity static final ChooserActivityOverrideData sOverrides = ChooserActivityOverrideData.getInstance(); private UsageStatsManager mUsm; + @Inject + public ChooserWrapperActivity(TestViewModelComponent.Builder builder) { + super(builder); + } + // ResolverActivity (the base class of ChooserActivity) inspects the launched-from UID at // onCreate and needs to see some non-negative value in the test. @Override diff --git a/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java b/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java index 401ede26..11e7dffd 100644 --- a/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java +++ b/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java @@ -44,6 +44,8 @@ import java.util.List; import java.util.function.Consumer; import java.util.function.Function; +import javax.inject.Inject; + /* * Simple wrapper around chooser activity to be able to initiate it under test */ @@ -53,6 +55,7 @@ public class ResolverWrapperActivity extends ResolverActivity { private final CountingIdlingResource mLabelIdlingResource = new CountingIdlingResource("LoadLabelTask"); + @Inject public ResolverWrapperActivity() { super(/* isIntentPicker= */ true); } diff --git a/java/tests/src/com/android/intentresolver/TestApplication.kt b/java/tests/src/com/android/intentresolver/TestApplication.kt index f0761fbd..4f5aefb9 100644 --- a/java/tests/src/com/android/intentresolver/TestApplication.kt +++ b/java/tests/src/com/android/intentresolver/TestApplication.kt @@ -16,32 +16,12 @@ package com.android.intentresolver -import android.app.Application import android.content.Context import android.os.UserHandle -import com.android.intentresolver.dagger.ApplicationComponent -import com.android.intentresolver.dagger.DaggerApplicationComponent +import com.android.intentresolver.dagger.DaggerTestApplicationComponent -class TestApplication : Application(), ApplicationComponentOwner { - - private lateinit var applicationComponent: ApplicationComponent - - private val pendingDaggerActions = mutableSetOf<(ApplicationComponent) -> Unit>() - - override fun onCreate() { - super.onCreate() - applicationComponent = DaggerApplicationComponent.builder().application(this).build() - pendingDaggerActions.forEach { it.invoke(applicationComponent) } - pendingDaggerActions.clear() - } - - override fun doWhenApplicationComponentReady(action: (ApplicationComponent) -> Unit) { - if (this::applicationComponent.isInitialized) { - action.invoke(applicationComponent) - } else { - pendingDaggerActions.add(action) - } - } +class TestApplication : IntentResolverApplication() { + override fun createApplicationComponentBuilder() = DaggerTestApplicationComponent.builder() // return the current context as a work profile doesn't really exist in these tests override fun createContextAsUser(user: UserHandle, flags: Int): Context = this diff --git a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java index ecd05b46..28a45051 100644 --- a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java +++ b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java @@ -864,7 +864,7 @@ public class UnbundledChooserActivityTest { } @Test - public void copyTextToClipboard() throws Exception { + public void copyTextToClipboard() { Intent sendIntent = createSendTextIntent(); List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2); @@ -879,7 +879,8 @@ public class UnbundledChooserActivityTest { ClipboardManager clipboard = (ClipboardManager) activity.getSystemService( Context.CLIPBOARD_SERVICE); ClipData clipData = clipboard.getPrimaryClip(); - assertThat("testing intent sending", is(clipData.getItemAt(0).getText())); + assertThat(clipData).isNotNull(); + assertThat(clipData.getItemAt(0).getText()).isEqualTo("testing intent sending"); ClipDescription clipDescription = clipData.getDescription(); assertThat("text/plain", is(clipDescription.getMimeType(0))); diff --git a/java/tests/src/com/android/intentresolver/dagger/TestActivityBinderModule.kt b/java/tests/src/com/android/intentresolver/dagger/TestActivityBinderModule.kt new file mode 100644 index 00000000..c08bc3b2 --- /dev/null +++ b/java/tests/src/com/android/intentresolver/dagger/TestActivityBinderModule.kt @@ -0,0 +1,40 @@ +/* + * 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.dagger + +import android.app.Activity +import com.android.intentresolver.ChooserWrapperActivity +import com.android.intentresolver.ResolverWrapperActivity +import dagger.Binds +import dagger.Module +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap + +@Module +interface TestActivityBinderModule { + @Binds + @IntoMap + @ClassKey(ResolverWrapperActivity::class) + @ActivityScope + fun resolverWrapperActivity(activity: ResolverWrapperActivity): Activity + + @Binds + @IntoMap + @ClassKey(ChooserWrapperActivity::class) + @ActivityScope + fun chooserWrapperActivity(activity: ChooserWrapperActivity): Activity +} diff --git a/java/tests/src/com/android/intentresolver/dagger/TestActivityComponent.kt b/java/tests/src/com/android/intentresolver/dagger/TestActivityComponent.kt new file mode 100644 index 00000000..4416c852 --- /dev/null +++ b/java/tests/src/com/android/intentresolver/dagger/TestActivityComponent.kt @@ -0,0 +1,30 @@ +/* + * 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.dagger + +import dagger.Subcomponent + +@ActivityScope +@Subcomponent( + modules = [ActivityModule::class, ActivityBinderModule::class, TestActivityBinderModule::class] +) +interface TestActivityComponent : ActivityComponent { + @Subcomponent.Factory + interface Factory : ActivityComponent.Factory { + override fun create(): TestActivityComponent + } +} diff --git a/java/tests/src/com/android/intentresolver/dagger/TestApplicationComponent.kt b/java/tests/src/com/android/intentresolver/dagger/TestApplicationComponent.kt new file mode 100644 index 00000000..224c46c6 --- /dev/null +++ b/java/tests/src/com/android/intentresolver/dagger/TestApplicationComponent.kt @@ -0,0 +1,34 @@ +/* + * 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.dagger + +import android.app.Application +import dagger.BindsInstance +import dagger.Component +import javax.inject.Singleton + +@Singleton +@Component(modules = [TestApplicationModule::class]) +interface TestApplicationComponent : ApplicationComponent { + @Component.Builder + interface Builder : ApplicationComponent.Builder { + @BindsInstance + override fun application(application: Application): TestApplicationComponent.Builder + + override fun build(): TestApplicationComponent + } +} diff --git a/java/tests/src/com/android/intentresolver/dagger/TestApplicationModule.kt b/java/tests/src/com/android/intentresolver/dagger/TestApplicationModule.kt new file mode 100644 index 00000000..714748d2 --- /dev/null +++ b/java/tests/src/com/android/intentresolver/dagger/TestApplicationModule.kt @@ -0,0 +1,38 @@ +/* + * 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.dagger + +import dagger.Binds +import dagger.Module +import javax.inject.Singleton + +@Module( + subcomponents = [TestActivityComponent::class, TestViewModelComponent::class], + includes = [ReceiverBinderModule::class, CoroutinesModule::class] +) +interface TestApplicationModule : ApplicationModule { + + /** Required to support field injection of [InjectedAppComponentFactory] */ + @Binds + @Singleton + fun activityComponent(component: TestActivityComponent.Factory): ActivityComponent.Factory + + /** Required to support injection into Activity instances */ + @Binds + @Singleton + fun viewModelComponent(component: TestViewModelComponent.Builder): ViewModelComponent.Builder +} diff --git a/java/tests/src/com/android/intentresolver/dagger/TestViewModelComponent.kt b/java/tests/src/com/android/intentresolver/dagger/TestViewModelComponent.kt new file mode 100644 index 00000000..539b3f36 --- /dev/null +++ b/java/tests/src/com/android/intentresolver/dagger/TestViewModelComponent.kt @@ -0,0 +1,29 @@ +/* + * 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.dagger + +import dagger.Subcomponent + +/** A ViewModelComponent for tests which replaces ViewModelModule -> TestViewModelModule */ +@ViewModelScope +@Subcomponent(modules = [TestViewModelModule::class, ViewModelBinderModule::class]) +interface TestViewModelComponent : ViewModelComponent { + @Subcomponent.Builder + interface Builder : ViewModelComponent.Builder { + override fun build(): TestViewModelComponent + } +} diff --git a/java/tests/src/com/android/intentresolver/dagger/TestViewModelModule.kt b/java/tests/src/com/android/intentresolver/dagger/TestViewModelModule.kt new file mode 100644 index 00000000..28f4fa73 --- /dev/null +++ b/java/tests/src/com/android/intentresolver/dagger/TestViewModelModule.kt @@ -0,0 +1,6 @@ +package com.android.intentresolver.dagger + +import dagger.Module + +/** Provides bindings shared among components within [@ViewModelScope][ViewModelScope]. */ +@Module abstract class TestViewModelModule |