diff --git a/BUILD b/BUILD index 8692ea11d58..15946a39e3e 100644 --- a/BUILD +++ b/BUILD @@ -101,7 +101,7 @@ android_library( name = "android_local_test_exports", exports = [ # TODO(bcorso): see if we can remove jsr250 dep from autovalue to prevent this. - "@javax_annotation_jsr250_api", # For @Generated + "@maven//:javax_annotation_jsr250_api", # For @Generated "@maven//:org_robolectric_shadows_framework", # For ActivityController "@maven//:androidx_lifecycle_lifecycle_common", # For Lifecycle.State "@maven//:androidx_activity_activity", # For ComponentActivity diff --git a/WORKSPACE b/WORKSPACE index c518009d6f9..bd202a9bce0 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -64,9 +64,9 @@ local_repository( http_archive( name = "google_bazel_common", - sha256 = "8b6aebdc095c8448b2f6a72bb8eae4a563891467e2d20c943f21940b1c444e38", - strip_prefix = "bazel-common-3d0e5005cfcbee836e31695d4ab91b5328ccc506", - urls = ["https://github.com/google/bazel-common/archive/3d0e5005cfcbee836e31695d4ab91b5328ccc506.zip"], + sha256 = "60a9aebe25f476646f61c041d1679a9b21076deffbd51526838c7f24d6468ac0", + strip_prefix = "bazel-common-227a23a508a2fab0fa67ffe2d9332ae536a40edc", + urls = ["https://github.com/google/bazel-common/archive/227a23a508a2fab0fa67ffe2d9332ae536a40edc.zip"], ) load("@google_bazel_common//:workspace_defs.bzl", "google_common_workspace_rules") @@ -161,9 +161,9 @@ kt_register_toolchains() # Load Maven dependencies ############################# -RULES_JVM_EXTERNAL_TAG = "2.7" +RULES_JVM_EXTERNAL_TAG = "4.2" -RULES_JVM_EXTERNAL_SHA = "f04b1466a00a2845106801e0c5cec96841f49ea4e7d1df88dc8e4bf31523df74" +RULES_JVM_EXTERNAL_SHA = "cd1a77b7b02e8e008439ca76fd34f5b07aecb8c752961f9640dea15e9e5ba1ca" http_archive( name = "rules_jvm_external", @@ -199,13 +199,16 @@ maven_install( artifacts = [ "androidx.annotation:annotation:1.1.0", "androidx.appcompat:appcompat:1.3.1", - "androidx.activity:activity:1.3.1", - "androidx.fragment:fragment:1.3.6", - "androidx.lifecycle:lifecycle-common:2.3.1", - "androidx.lifecycle:lifecycle-viewmodel:2.3.1", - "androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.1", + "androidx.activity:activity:1.5.0", + "androidx.fragment:fragment:1.5.0", + "androidx.lifecycle:lifecycle-common:2.5.0", + "androidx.lifecycle:lifecycle-viewmodel:2.5.0", + "androidx.lifecycle:lifecycle-viewmodel-savedstate:2.5.0", "androidx.multidex:multidex:2.0.1", - "androidx.savedstate:savedstate:1.0.0", + "androidx.navigation:navigation-common:2.5.0", + "androidx.navigation:navigation-fragment:2.5.0", + "androidx.navigation:navigation-runtime:2.5.0", + "androidx.savedstate:savedstate:1.2.0", "androidx.test:monitor:1.4.0", "androidx.test:core:1.4.0", "androidx.test.ext:junit:1.1.3", diff --git a/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java b/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java index 4e2e0fa8bb4..53163f0c571 100644 --- a/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java +++ b/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java @@ -24,6 +24,7 @@ import androidx.lifecycle.SavedStateHandle; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; +import androidx.lifecycle.viewmodel.CreationExtras; import androidx.savedstate.SavedStateRegistryOwner; import dagger.Module; import dagger.hilt.EntryPoint; @@ -78,7 +79,7 @@ public HiltViewModelFactory( this.hiltViewModelKeys = hiltViewModelKeys; this.delegateFactory = delegateFactory; this.hiltViewModelFactory = - new AbstractSavedStateViewModelFactory(owner, defaultArgs) { + new AbstractSavedStateViewModelFactory() { @NonNull @Override @SuppressWarnings("unchecked") @@ -102,6 +103,17 @@ protected T create( }; } + @NonNull + @Override + public T create( + @NonNull Class modelClass, @NonNull CreationExtras extras) { + if (hiltViewModelKeys.contains(modelClass.getName())) { + return hiltViewModelFactory.create(modelClass, extras); + } else { + return delegateFactory.create(modelClass, extras); + } + } + @NonNull @Override public T create(@NonNull Class modelClass) { diff --git a/javatests/dagger/android/processor/BUILD b/javatests/dagger/android/processor/BUILD index 4dbd260743d..79283eb4f27 100644 --- a/javatests/dagger/android/processor/BUILD +++ b/javatests/dagger/android/processor/BUILD @@ -35,7 +35,7 @@ GenJavaTests( "//third_party/java/guava/collect", "//third_party/java/junit", "//third_party/java/truth", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "@maven//:androidx_activity_activity", "@maven//:androidx_fragment_fragment", "@maven//:androidx_lifecycle_lifecycle_common", diff --git a/javatests/dagger/hilt/android/AndroidManifest.xml b/javatests/dagger/hilt/android/AndroidManifest.xml index 5195ca61c69..3c0fa840d1c 100644 --- a/javatests/dagger/hilt/android/AndroidManifest.xml +++ b/javatests/dagger/hilt/android/AndroidManifest.xml @@ -65,6 +65,10 @@ android:name=".ViewModelScopedTest$TestActivity" android:exported="false" tools:ignore="MissingClass"/> + scenario = ActivityScenario.launch(TestActivity.class)) { + scenario.onActivity( + activity -> { + NavController navController = + Navigation.findNavController(activity, R.id.nav_host_fragment); + TestFragment startFragment = findTestFragment(activity); + + MyViewModel activityVm = + getViewModel(activity, activity.getDefaultViewModelProviderFactory()); + MyViewModel fragmentVm = + getViewModel(startFragment, startFragment.getDefaultViewModelProviderFactory()); + MyViewModel fragmentBackStackVm = + getViewModel( + navController.getBackStackEntry(R.id.start_destination), + startFragment.getDefaultViewModelProviderFactory()); + MyViewModel navGraphVm = + getViewModel( + navController.getBackStackEntry(R.id.nav_graph), + startFragment.getDefaultViewModelProviderFactory()); + + // The activity shouldn't have any arguments since it was only set on the fragment. + assertThat((String) activityVm.savedStateHandle.get("argument_key")).isNull(); + activityVm.savedStateHandle.set("other_key", "activity_other_key"); + + // The fragment argument (set in the navgraph xml) should be set. + assertThat((String) fragmentVm.savedStateHandle.get("argument_key")) + .isEqualTo("fragment_argument"); + fragmentVm.savedStateHandle.set("other_key", "fragment_other_key"); + + // The back stack entry also has the fragment arguments + assertThat((String) fragmentBackStackVm.savedStateHandle.get("argument_key")) + .isEqualTo("fragment_argument"); + fragmentBackStackVm.savedStateHandle.set("other_key", "fragment_backstack_other_key"); + + // When the nav graph itself is the owner, then there should be no arguments. + assertThat((String) navGraphVm.savedStateHandle.get("argument_key")).isNull(); + navGraphVm.savedStateHandle.set("other_key", "nav_graph_other_key"); + + navController.navigate(R.id.next_destination); + }); + + // Now move to the next fragment to compare + scenario.onActivity( + activity -> { + NavController navController = + Navigation.findNavController(activity, R.id.nav_host_fragment); + + TestFragment nextFragment = findTestFragment(activity); + + MyViewModel activityVm = + getViewModel(activity, activity.getDefaultViewModelProviderFactory()); + MyViewModel fragmentVm = + getViewModel(nextFragment, nextFragment.getDefaultViewModelProviderFactory()); + MyViewModel navGraphVm = + getViewModel( + navController.getBackStackEntry(R.id.nav_graph), + nextFragment.getDefaultViewModelProviderFactory()); + MyViewModel fragmentBackStackVm = + getViewModel( + navController.getBackStackEntry(R.id.next_destination), + nextFragment.getDefaultViewModelProviderFactory()); + + // The activity still shouldn't have any arguments, but since it is the same + // owner (since the activity didn't change), the other key should still be set + // from before. + assertThat((String) activityVm.savedStateHandle.get("argument_key")).isNull(); + assertThat((String) activityVm.savedStateHandle.get("other_key")) + .isEqualTo("activity_other_key"); + + // The fragment argument should be set via the navgraph xml again. Also, since + // this is a new fragment, the other key should not be set. + assertThat((String) fragmentVm.savedStateHandle.get("argument_key")) + .isEqualTo("next_fragment_argument"); + assertThat((String) fragmentVm.savedStateHandle.get("other_key")).isNull(); + + // Same as using the fragment as the owner. + assertThat((String) fragmentBackStackVm.savedStateHandle.get("argument_key")) + .isEqualTo("next_fragment_argument"); + assertThat((String) fragmentBackStackVm.savedStateHandle.get("other_key")).isNull(); + + // Similar to the activity case, the navgraph is the same so we expect the same + // key to be set from before. Arguments should still be missing. + assertThat((String) navGraphVm.savedStateHandle.get("argument_key")).isNull(); + assertThat((String) navGraphVm.savedStateHandle.get("other_key")) + .isEqualTo("nav_graph_other_key"); + }); + } + } + + private TestFragment findTestFragment(FragmentActivity activity) { + return (TestFragment) + activity + .getSupportFragmentManager() + .findFragmentById(R.id.nav_host_fragment) + .getChildFragmentManager() + .getPrimaryNavigationFragment(); + } + + private MyViewModel getViewModel(ViewModelStoreOwner owner, ViewModelProvider.Factory factory) { + return new ViewModelProvider(owner, factory).get(MyViewModel.class); + } + + @AndroidEntryPoint(FragmentActivity.class) + public static class TestActivity extends Hilt_ViewModelSavedStateOwnerTest_TestActivity { + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.navigation_activity); + } + } + + @AndroidEntryPoint(Fragment.class) + public static class TestFragment extends Hilt_ViewModelSavedStateOwnerTest_TestFragment { + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + } + + @HiltViewModel + static class MyViewModel extends ViewModel { + final SavedStateHandle savedStateHandle; + + @Inject + MyViewModel(SavedStateHandle savedStateHandle) { + this.savedStateHandle = savedStateHandle; + } + } +} diff --git a/javatests/dagger/hilt/android/ViewModelScopedTest.java b/javatests/dagger/hilt/android/ViewModelScopedTest.java index 4c912ad1998..17aca32bb7a 100644 --- a/javatests/dagger/hilt/android/ViewModelScopedTest.java +++ b/javatests/dagger/hilt/android/ViewModelScopedTest.java @@ -53,7 +53,13 @@ public void testViewModelScopeInFragment() { activity -> { TestFragment fragment = (TestFragment) activity.getSupportFragmentManager().findFragmentByTag("tag"); - assertThat(fragment.vm.one.bar).isEqualTo(fragment.vm.two.bar); + // Check that the scoped bar is the same instance within the same view model. + assertThat(fragment.vm1.one.bar).isEqualTo(fragment.vm1.two.bar); + assertThat(fragment.vm2.one.bar).isEqualTo(fragment.vm2.two.bar); + + // Check that the keyed viewmodels are separate by checking that the bar instances + // are different, and hence have different components. + assertThat(fragment.vm1.one.bar).isNotEqualTo(fragment.vm2.one.bar); }); } } @@ -76,12 +82,14 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { @AndroidEntryPoint(Fragment.class) public static class TestFragment extends Hilt_ViewModelScopedTest_TestFragment { - MyViewModel vm; + MyViewModel vm1; + MyViewModel vm2; @Override public void onCreate(@Nullable Bundle bundle) { super.onCreate(bundle); - vm = new ViewModelProvider(this).get(MyViewModel.class); + vm1 = new ViewModelProvider(this).get("foo", MyViewModel.class); + vm2 = new ViewModelProvider(this).get("bar", MyViewModel.class); } } diff --git a/javatests/dagger/hilt/android/processor/internal/BUILD b/javatests/dagger/hilt/android/processor/internal/BUILD index 513173f1557..21496de5f44 100644 --- a/javatests/dagger/hilt/android/processor/internal/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/BUILD @@ -24,7 +24,7 @@ compiler_test( compiler_deps = [ "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android:android_entry_point", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "@maven//:androidx_annotation_annotation", ], deps = [ diff --git a/javatests/dagger/hilt/android/processor/internal/aggregateddeps/BUILD b/javatests/dagger/hilt/android/processor/internal/aggregateddeps/BUILD index 79a45c4e55a..09f331e7855 100644 --- a/javatests/dagger/hilt/android/processor/internal/aggregateddeps/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/aggregateddeps/BUILD @@ -30,7 +30,7 @@ compiler_test( "//java/dagger/hilt/android/internal/modules", "//java/dagger/hilt/testing:test_install_in", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", ], deps = [ "//third_party/java/compile_testing", @@ -49,7 +49,7 @@ compiler_test( "//java/dagger/hilt/android:early_entry_point", "//java/dagger/hilt/android/components", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", ], deps = [ "//third_party/java/compile_testing", diff --git a/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD b/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD index d69f50483a7..1082a233b7b 100644 --- a/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD @@ -23,7 +23,7 @@ compiler_test( srcs = ["ActivityGeneratorTest.java"], compiler_deps = [ "//java/dagger/hilt/android:android_entry_point", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", ], deps = [ "//third_party/java/compile_testing", @@ -39,7 +39,7 @@ compiler_test( compiler_deps = [ "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android:android_entry_point", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", ], deps = [ "//third_party/java/compile_testing", @@ -55,7 +55,7 @@ kt_compiler_test( compiler_deps = [ "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android:android_entry_point", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", ], deps = [ "//third_party/java/guava/collect", diff --git a/javatests/dagger/hilt/android/processor/internal/customtestapplication/BUILD b/javatests/dagger/hilt/android/processor/internal/customtestapplication/BUILD index 2e564ec78d2..001807459e1 100644 --- a/javatests/dagger/hilt/android/processor/internal/customtestapplication/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/customtestapplication/BUILD @@ -25,7 +25,7 @@ compiler_test( "//java/dagger/hilt/android/testing:custom_test_application", "//java/dagger/hilt/android/testing:hilt_android_test", "//java/dagger/hilt/android:hilt_android_app", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", ], deps = [ "//third_party/java/compile_testing", diff --git a/javatests/dagger/hilt/android/processor/internal/viewmodel/BUILD b/javatests/dagger/hilt/android/processor/internal/viewmodel/BUILD index 86342bd198a..a08b756fd5b 100644 --- a/javatests/dagger/hilt/android/processor/internal/viewmodel/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/viewmodel/BUILD @@ -27,7 +27,7 @@ java_test( "//java/dagger/hilt/android/lifecycle", "//third_party/java/compile_testing", "//third_party/java/truth", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "@maven//:androidx_lifecycle_lifecycle_viewmodel", "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate", ], @@ -54,7 +54,7 @@ java_test( "//java/dagger/hilt/android/lifecycle", "//third_party/java/compile_testing", "//third_party/java/truth", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "@maven//:androidx_lifecycle_lifecycle_viewmodel", "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate", ], @@ -80,7 +80,7 @@ kt_compiler_test( "ViewModelValidationPluginTest.kt", ], compiler_deps = [ - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "@maven//:androidx_lifecycle_lifecycle_viewmodel", "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate", "//third_party/java/compile_testing", diff --git a/javatests/dagger/hilt/android/res/layout/navigation_activity.xml b/javatests/dagger/hilt/android/res/layout/navigation_activity.xml new file mode 100644 index 00000000000..ec6365d7a37 --- /dev/null +++ b/javatests/dagger/hilt/android/res/layout/navigation_activity.xml @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/javatests/dagger/hilt/android/res/navigation/nav_graph.xml b/javatests/dagger/hilt/android/res/navigation/nav_graph.xml new file mode 100644 index 00000000000..5e1331e3192 --- /dev/null +++ b/javatests/dagger/hilt/android/res/navigation/nav_graph.xml @@ -0,0 +1,22 @@ + + + + + + + + + + \ No newline at end of file diff --git a/javatests/dagger/hilt/processor/internal/aliasof/BUILD b/javatests/dagger/hilt/processor/internal/aliasof/BUILD index 3a7b4af6819..c027532cfc1 100644 --- a/javatests/dagger/hilt/processor/internal/aliasof/BUILD +++ b/javatests/dagger/hilt/processor/internal/aliasof/BUILD @@ -24,7 +24,7 @@ compiler_test( size = "small", srcs = ["AliasOfProcessorTest.java"], compiler_deps = [ - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "//third_party/java/jsr330_inject", "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android/components", diff --git a/javatests/dagger/hilt/processor/internal/originatingelement/BUILD b/javatests/dagger/hilt/processor/internal/originatingelement/BUILD index c45cfb6e988..055e695ad0a 100644 --- a/javatests/dagger/hilt/processor/internal/originatingelement/BUILD +++ b/javatests/dagger/hilt/processor/internal/originatingelement/BUILD @@ -24,7 +24,7 @@ compiler_test( srcs = ["OriginatingElementProcessorTest.java"], compiler_deps = [ "//java/dagger/hilt/codegen:originating_element", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "@maven//:androidx_annotation_annotation", ], deps = [ diff --git a/javatests/dagger/hilt/processor/internal/root/BUILD b/javatests/dagger/hilt/processor/internal/root/BUILD index ef2344c1d03..7f55cdd63e4 100644 --- a/javatests/dagger/hilt/processor/internal/root/BUILD +++ b/javatests/dagger/hilt/processor/internal/root/BUILD @@ -33,7 +33,7 @@ compiler_test( ":MyAppPreviousCompilation", "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "@maven//:androidx_annotation_annotation", "@maven//:org_robolectric_robolectric", "@maven//:androidx_test_ext_junit", @@ -64,7 +64,7 @@ compiler_test( ":MyTestPreviousCompilation", "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "@maven//:androidx_annotation_annotation", "@maven//:org_robolectric_robolectric", "@maven//:androidx_test_ext_junit", @@ -85,7 +85,7 @@ compiler_test( compiler_deps = [ "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "@maven//:androidx_annotation_annotation", "@maven//:org_robolectric_robolectric", "@maven//:androidx_test_ext_junit", @@ -106,7 +106,7 @@ compiler_test( compiler_deps = [ "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "@maven//:androidx_annotation_annotation", "@maven//:org_robolectric_robolectric", "@maven//:androidx_test_ext_junit", diff --git a/javatests/dagger/hilt/processor/internal/uninstallmodules/BUILD b/javatests/dagger/hilt/processor/internal/uninstallmodules/BUILD index e407193b498..b669243d762 100644 --- a/javatests/dagger/hilt/processor/internal/uninstallmodules/BUILD +++ b/javatests/dagger/hilt/processor/internal/uninstallmodules/BUILD @@ -27,7 +27,7 @@ compiler_test( "//java/dagger/hilt/android/testing:hilt_android_test", "//java/dagger/hilt/android/testing:uninstall_modules", "//java/dagger/hilt/migration:disable_install_in_check", - "@androidsdk//:platforms/android-30/android.jar", + "@androidsdk//:platforms/android-31/android.jar", "@maven//:androidx_annotation_annotation", ], deps = [