• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Dagger Authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package dagger.hilt.android.internal.lifecycle;
18 
19 import static dagger.hilt.internal.Preconditions.checkNotNull;
20 
21 import androidx.fragment.app.Fragment;
22 import androidx.activity.ComponentActivity;
23 import androidx.lifecycle.ViewModelProvider;
24 import dagger.Module;
25 import dagger.hilt.EntryPoint;
26 import dagger.hilt.EntryPoints;
27 import dagger.hilt.InstallIn;
28 import dagger.hilt.android.components.ActivityComponent;
29 import dagger.hilt.android.components.FragmentComponent;
30 import dagger.hilt.android.internal.builders.ViewModelComponentBuilder;
31 import dagger.multibindings.Multibinds;
32 import java.util.Map;
33 import javax.inject.Inject;
34 
35 /**
36  * Modules and entry points for the default view model factory used by activities and fragments
37  * annotated with @AndroidEntryPoint.
38  *
39  * <p>Entry points are used to acquire the factory because injected fields in the generated
40  * activities and fragments are ignored by Dagger when using the transform due to the generated
41  * class not being part of the hierarchy during compile time.
42  */
43 public final class DefaultViewModelFactories {
44 
45   /**
46    * Retrieves the default view model factory for the activity.
47    *
48    * <p>Do not use except in Hilt generated code!
49    */
getActivityFactory(ComponentActivity activity, ViewModelProvider.Factory delegateFactory)50   public static ViewModelProvider.Factory getActivityFactory(ComponentActivity activity,
51       ViewModelProvider.Factory delegateFactory) {
52     return EntryPoints.get(activity, ActivityEntryPoint.class)
53         .getHiltInternalFactoryFactory()
54         .fromActivity(activity, delegateFactory);
55   }
56 
57   /**
58    * Retrieves the default view model factory for the activity.
59    *
60    * <p>Do not use except in Hilt generated code!
61    */
getFragmentFactory( Fragment fragment, ViewModelProvider.Factory delegateFactory)62   public static ViewModelProvider.Factory getFragmentFactory(
63       Fragment fragment, ViewModelProvider.Factory delegateFactory) {
64     return EntryPoints.get(fragment, FragmentEntryPoint.class)
65         .getHiltInternalFactoryFactory()
66         .fromFragment(fragment, delegateFactory);
67   }
68 
69   /** Internal factory for the Hilt ViewModel Factory. */
70   public static final class InternalFactoryFactory {
71 
72     private final Map<Class<?>, Boolean> keySet;
73     private final ViewModelComponentBuilder viewModelComponentBuilder;
74 
75     @Inject
InternalFactoryFactory( @iltViewModelMap.KeySet Map<Class<?>, Boolean> keySet, ViewModelComponentBuilder viewModelComponentBuilder)76     InternalFactoryFactory(
77         @HiltViewModelMap.KeySet Map<Class<?>, Boolean> keySet,
78         ViewModelComponentBuilder viewModelComponentBuilder) {
79       this.keySet = keySet;
80       this.viewModelComponentBuilder = viewModelComponentBuilder;
81     }
82 
fromActivity( ComponentActivity activity, ViewModelProvider.Factory delegateFactory)83     ViewModelProvider.Factory fromActivity(
84         ComponentActivity activity, ViewModelProvider.Factory delegateFactory) {
85       return getHiltViewModelFactory(
86           delegateFactory);
87     }
88 
fromFragment( Fragment fragment, ViewModelProvider.Factory delegateFactory)89     ViewModelProvider.Factory fromFragment(
90         Fragment fragment, ViewModelProvider.Factory delegateFactory) {
91       return getHiltViewModelFactory(delegateFactory);
92     }
93 
getHiltViewModelFactory( ViewModelProvider.Factory delegate)94     private ViewModelProvider.Factory getHiltViewModelFactory(
95         ViewModelProvider.Factory delegate) {
96       return new HiltViewModelFactory(keySet, checkNotNull(delegate), viewModelComponentBuilder);
97     }
98   }
99 
100   /** The activity module to declare the optional factories. */
101   @Module
102   @InstallIn(ActivityComponent.class)
103   interface ActivityModule {
104     @Multibinds
105     @HiltViewModelMap.KeySet
viewModelKeys()106     abstract Map<Class<?>, Boolean> viewModelKeys();
107   }
108 
109   /** The activity entry point to retrieve the factory. */
110   @EntryPoint
111   @InstallIn(ActivityComponent.class)
112   public interface ActivityEntryPoint {
getHiltInternalFactoryFactory()113     InternalFactoryFactory getHiltInternalFactoryFactory();
114   }
115 
116   /** The fragment entry point to retrieve the factory. */
117   @EntryPoint
118   @InstallIn(FragmentComponent.class)
119   public interface FragmentEntryPoint {
getHiltInternalFactoryFactory()120     InternalFactoryFactory getHiltInternalFactoryFactory();
121   }
122 
DefaultViewModelFactories()123   private DefaultViewModelFactories() {}
124 }
125