diff --git a/java/dagger/hilt/android/internal/lifecycle/DefaultActivityViewModelFactory.java b/java/dagger/hilt/android/internal/lifecycle/DefaultActivityViewModelFactory.java
deleted file mode 100644
index becce8cdb23..00000000000
--- a/java/dagger/hilt/android/internal/lifecycle/DefaultActivityViewModelFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2020 The Dagger Authors.
- *
- * 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 dagger.hilt.android.internal.lifecycle;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import javax.inject.Qualifier;
-
-/** Qualifier for the default view model factory used by @AndroidEntryPoint annotated activities. */
-@Qualifier
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
-public @interface DefaultActivityViewModelFactory {}
diff --git a/java/dagger/hilt/android/internal/lifecycle/DefaultFragmentViewModelFactory.java b/java/dagger/hilt/android/internal/lifecycle/DefaultFragmentViewModelFactory.java
deleted file mode 100644
index 996705376ba..00000000000
--- a/java/dagger/hilt/android/internal/lifecycle/DefaultFragmentViewModelFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2020 The Dagger Authors.
- *
- * 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 dagger.hilt.android.internal.lifecycle;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import javax.inject.Qualifier;
-
-/** Qualifier for the default view model factory used by @AndroidEntryPoint annotated fragments. */
-@Qualifier
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
-public @interface DefaultFragmentViewModelFactory {}
diff --git a/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java b/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java
index 427822dbbac..448847cd3b8 100644
--- a/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java
+++ b/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java
@@ -50,10 +50,11 @@ public final class DefaultViewModelFactories {
*
*
Do not use except in Hilt generated code!
*/
- public static ViewModelProvider.Factory getActivityFactory(ComponentActivity activity) {
+ public static ViewModelProvider.Factory getActivityFactory(ComponentActivity activity,
+ ViewModelProvider.Factory delegateFactory) {
return EntryPoints.get(activity, ActivityEntryPoint.class)
.getHiltInternalFactoryFactory()
- .fromActivity(activity);
+ .fromActivity(activity, delegateFactory);
}
/**
@@ -61,10 +62,11 @@ public static ViewModelProvider.Factory getActivityFactory(ComponentActivity act
*
*
Do not use except in Hilt generated code!
*/
- public static ViewModelProvider.Factory getFragmentFactory(Fragment fragment) {
+ public static ViewModelProvider.Factory getFragmentFactory(
+ Fragment fragment, ViewModelProvider.Factory delegateFactory) {
return EntryPoints.get(fragment, FragmentEntryPoint.class)
.getHiltInternalFactoryFactory()
- .fromFragment(fragment);
+ .fromFragment(fragment, delegateFactory);
}
/** Internal factory for the Hilt ViewModel Factory. */
@@ -73,33 +75,28 @@ public static final class InternalFactoryFactory {
private final Application application;
private final Set keySet;
private final ViewModelComponentBuilder viewModelComponentBuilder;
- @Nullable private final ViewModelProvider.Factory defaultActivityFactory;
- @Nullable private final ViewModelProvider.Factory defaultFragmentFactory;
@Inject
InternalFactoryFactory(
Application application,
@HiltViewModelMap.KeySet Set keySet,
- ViewModelComponentBuilder viewModelComponentBuilder,
- // These default factory bindings are temporary for the transition of deprecating
- // the Hilt ViewModel extension for the built-in support
- @DefaultActivityViewModelFactory Set defaultActivityFactorySet,
- @DefaultFragmentViewModelFactory Set defaultFragmentFactorySet) {
+ ViewModelComponentBuilder viewModelComponentBuilder) {
this.application = application;
this.keySet = keySet;
this.viewModelComponentBuilder = viewModelComponentBuilder;
- this.defaultActivityFactory = getFactoryFromSet(defaultActivityFactorySet);
- this.defaultFragmentFactory = getFactoryFromSet(defaultFragmentFactorySet);
}
- ViewModelProvider.Factory fromActivity(ComponentActivity activity) {
- return getHiltViewModelFactory(activity,
+ ViewModelProvider.Factory fromActivity(
+ ComponentActivity activity, ViewModelProvider.Factory delegateFactory) {
+ return getHiltViewModelFactory(
+ activity,
activity.getIntent() != null ? activity.getIntent().getExtras() : null,
- defaultActivityFactory);
+ delegateFactory);
}
- ViewModelProvider.Factory fromFragment(Fragment fragment) {
- return getHiltViewModelFactory(fragment, fragment.getArguments(), defaultFragmentFactory);
+ ViewModelProvider.Factory fromFragment(
+ Fragment fragment, ViewModelProvider.Factory delegateFactory) {
+ return getHiltViewModelFactory(fragment, fragment.getArguments(), delegateFactory);
}
private ViewModelProvider.Factory getHiltViewModelFactory(
@@ -112,24 +109,6 @@ private ViewModelProvider.Factory getHiltViewModelFactory(
return new HiltViewModelFactory(
owner, defaultArgs, keySet, delegate, viewModelComponentBuilder);
}
-
- @Nullable
- private static ViewModelProvider.Factory getFactoryFromSet(Set set) {
- // A multibinding set is used instead of BindsOptionalOf because Optional is not available in
- // Android until API 24 and we don't want to have Guava as a transitive dependency.
- if (set.isEmpty()) {
- return null;
- }
- if (set.size() > 1) {
- throw new IllegalStateException(
- "At most one default view model factory is expected. Found " + set);
- }
- ViewModelProvider.Factory factory = set.iterator().next();
- if (factory == null) {
- throw new IllegalStateException("Default view model factory must not be null.");
- }
- return factory;
- }
}
/** The activity module to declare the optional factories. */
@@ -139,14 +118,6 @@ interface ActivityModule {
@Multibinds
@HiltViewModelMap.KeySet
abstract Set viewModelKeys();
-
- @Multibinds
- @DefaultActivityViewModelFactory
- Set defaultActivityViewModelFactory();
-
- @Multibinds
- @DefaultFragmentViewModelFactory
- Set defaultFragmentViewModelFactory();
}
/** The activity entry point to retrieve the factory. */
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java
index 6069d608b44..86fbaa71260 100644
--- a/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java
+++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java
@@ -108,7 +108,8 @@ private MethodSpec init() {
// @Override
// public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
- // return DefaultViewModelFactories.getActivityFactory(this);
+ // return DefaultViewModelFactories.getActivityFactory(
+ // this, super.getDefaultViewModelProviderFactory());
// }
private MethodSpec getDefaultViewModelProviderFactory() {
return MethodSpec.methodBuilder("getDefaultViewModelProviderFactory")
@@ -116,7 +117,7 @@ private MethodSpec getDefaultViewModelProviderFactory() {
.addModifiers(Modifier.PUBLIC)
.returns(AndroidClassNames.VIEW_MODEL_PROVIDER_FACTORY)
.addStatement(
- "return $T.getActivityFactory(this)",
+ "return $T.getActivityFactory(this, super.getDefaultViewModelProviderFactory())",
AndroidClassNames.DEFAULT_VIEW_MODEL_FACTORIES)
.build();
}
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/FragmentGenerator.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/FragmentGenerator.java
index 4ef479f46b5..81b2b615642 100644
--- a/java/dagger/hilt/android/processor/internal/androidentrypoint/FragmentGenerator.java
+++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/FragmentGenerator.java
@@ -202,7 +202,8 @@ private MethodSpec inflatorMethod() {
// @Override
// public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
- // return DefaultViewModelFactories.getFragmentFactory(this);
+ // return DefaultViewModelFactories.getFragmentFactory(
+ // this, super.getDefaultViewModelProviderFactory());
// }
private MethodSpec getDefaultViewModelProviderFactory() {
return MethodSpec.methodBuilder("getDefaultViewModelProviderFactory")
@@ -210,7 +211,7 @@ private MethodSpec getDefaultViewModelProviderFactory() {
.addModifiers(Modifier.PUBLIC)
.returns(AndroidClassNames.VIEW_MODEL_PROVIDER_FACTORY)
.addStatement(
- "return $T.getFragmentFactory(this)",
+ "return $T.getFragmentFactory(this, super.getDefaultViewModelProviderFactory())",
AndroidClassNames.DEFAULT_VIEW_MODEL_FACTORIES)
.build();
}
diff --git a/javatests/artifacts/hilt-android/simple/app/build.gradle b/javatests/artifacts/hilt-android/simple/app/build.gradle
index 98b79e1883e..1d76ec26cc3 100644
--- a/javatests/artifacts/hilt-android/simple/app/build.gradle
+++ b/javatests/artifacts/hilt-android/simple/app/build.gradle
@@ -97,7 +97,6 @@ dependencies {
// To help us catch version skew related issues in hilt extensions.
// TODO(bcorso): Add examples testing the actual API.
- implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'
implementation 'androidx.hilt:hilt-work:1.0.0-alpha01'
annotationProcessor 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
testAnnotationProcessor 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
diff --git a/javatests/dagger/hilt/android/BUILD b/javatests/dagger/hilt/android/BUILD
index 982862ff2ea..3205b84fd62 100644
--- a/javatests/dagger/hilt/android/BUILD
+++ b/javatests/dagger/hilt/android/BUILD
@@ -293,6 +293,7 @@ android_local_test(
"//java/dagger/hilt/android:android_entry_point",
"//java/dagger/hilt/android:package_info",
"//java/dagger/hilt/android/lifecycle",
+ "//java/dagger/hilt/android/testing:bind_value",
"//java/dagger/hilt/android/testing:hilt_android_test",
"@google_bazel_common//third_party/java/jsr330_inject",
"@google_bazel_common//third_party/java/truth",
diff --git a/javatests/dagger/hilt/android/DefaultViewModelFactoryTest.java b/javatests/dagger/hilt/android/DefaultViewModelFactoryTest.java
index 00471903afc..78cd5688a3e 100644
--- a/javatests/dagger/hilt/android/DefaultViewModelFactoryTest.java
+++ b/javatests/dagger/hilt/android/DefaultViewModelFactoryTest.java
@@ -18,15 +18,19 @@
import static com.google.common.truth.Truth.assertThat;
+import androidx.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModelProvider;
import android.os.Build;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.test.core.app.ActivityScenario;
import androidx.test.ext.junit.runners.AndroidJUnit4;
-import dagger.hilt.android.internal.lifecycle.HiltViewModelFactory;
+import dagger.hilt.android.lifecycle.HiltViewModel;
+import dagger.hilt.android.testing.BindValue;
import dagger.hilt.android.testing.HiltAndroidRule;
import dagger.hilt.android.testing.HiltAndroidTest;
import dagger.hilt.android.testing.HiltTestApplication;
+import javax.inject.Inject;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -40,36 +44,82 @@ public class DefaultViewModelFactoryTest {
@Rule public final HiltAndroidRule rule = new HiltAndroidRule(this);
+ @BindValue String hiltStringValue = "hilt";
+
@Test
- public void activityFactory() {
+ public void activityFactoryFallsBackToBase() {
try (ActivityScenario scenario = ActivityScenario.launch(TestActivity.class)) {
scenario.onActivity(
activity -> {
- assertThat(activity.getDefaultViewModelProviderFactory()).isNotNull();
- assertThat(activity.getDefaultViewModelProviderFactory())
- .isInstanceOf(HiltViewModelFactory.class);
+ assertThat(new ViewModelProvider(activity).get(TestHiltViewModel.class).value)
+ .isEqualTo("hilt");
+ assertThat(new ViewModelProvider(activity).get(TestViewModel.class).value)
+ .isEqualTo("non-hilt");
});
}
}
@Test
- public void fragmentFactory() {
+ public void fragmentFactoryFallbsBackToBase() {
// TODO(danysantiago): Use FragmentScenario when it becomes available.
try (ActivityScenario scenario = ActivityScenario.launch(TestActivity.class)) {
scenario.onActivity(
activity -> {
TestFragment fragment = new TestFragment();
activity.getSupportFragmentManager().beginTransaction().add(fragment, "").commitNow();
- assertThat(fragment.getDefaultViewModelProviderFactory()).isNotNull();
- assertThat(fragment.getDefaultViewModelProviderFactory())
- .isInstanceOf(HiltViewModelFactory.class);
+ assertThat(new ViewModelProvider(fragment).get(TestHiltViewModel.class).value)
+ .isEqualTo("hilt");
+ assertThat(new ViewModelProvider(fragment).get(TestViewModel.class).value)
+ .isEqualTo("non-hilt");
});
}
}
- @AndroidEntryPoint(FragmentActivity.class)
+ @HiltViewModel
+ public static final class TestHiltViewModel extends ViewModel {
+ final String value;
+
+ @Inject
+ TestHiltViewModel(String value) {
+ this.value = value;
+ }
+ }
+
+ public static final class TestViewModel extends ViewModel {
+ final String value;
+ // Take in a string so it cannot be constructed by the default view model factory
+ public TestViewModel(String value) {
+ this.value = value;
+ }
+ }
+
+ @AndroidEntryPoint(BaseActivity.class)
public static final class TestActivity extends Hilt_DefaultViewModelFactoryTest_TestActivity {}
- @AndroidEntryPoint(Fragment.class)
+ public static class BaseActivity extends FragmentActivity {
+ @SuppressWarnings("unchecked")
+ @Override public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
+ return new ViewModelProvider.Factory() {
+ @Override public T create(Class clazz) {
+ assertThat(clazz).isEqualTo(TestViewModel.class);
+ return (T) new TestViewModel("non-hilt");
+ }
+ };
+ }
+ }
+
+ @AndroidEntryPoint(BaseFragment.class)
public static final class TestFragment extends Hilt_DefaultViewModelFactoryTest_TestFragment {}
+
+ public static class BaseFragment extends Fragment {
+ @SuppressWarnings("unchecked")
+ @Override public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
+ return new ViewModelProvider.Factory() {
+ @Override public T create(Class clazz) {
+ assertThat(clazz).isEqualTo(TestViewModel.class);
+ return (T) new TestViewModel("non-hilt");
+ }
+ };
+ }
+ }
}