• 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 android.app.Application;
20 import androidx.lifecycle.SavedStateViewModelFactory;
21 import androidx.lifecycle.ViewModelProvider;
22 import android.os.Bundle;
23 import androidx.annotation.Nullable;
24 import androidx.fragment.app.Fragment;
25 import androidx.activity.ComponentActivity;
26 import androidx.savedstate.SavedStateRegistryOwner;
27 import dagger.Module;
28 import dagger.hilt.EntryPoint;
29 import dagger.hilt.EntryPoints;
30 import dagger.hilt.InstallIn;
31 import dagger.hilt.android.components.ActivityComponent;
32 import dagger.hilt.android.components.FragmentComponent;
33 import dagger.hilt.android.internal.builders.ViewModelComponentBuilder;
34 import dagger.multibindings.Multibinds;
35 import java.util.Set;
36 import javax.inject.Inject;
37 
38 /**
39  * Modules and entry points for the default view model factory used by activities and fragments
40  * annotated with @AndroidEntryPoint.
41  *
42  * <p>Entry points are used to acquire the factory because injected fields in the generated
43  * activities and fragments are ignored by Dagger when using the transform due to the generated
44  * class not being part of the hierarchy during compile time.
45  */
46 public final class DefaultViewModelFactories {
47 
48   /**
49    * Retrieves the default view model factory for the activity.
50    *
51    * <p>Do not use except in Hilt generated code!
52    */
getActivityFactory(ComponentActivity activity, ViewModelProvider.Factory delegateFactory)53   public static ViewModelProvider.Factory getActivityFactory(ComponentActivity activity,
54       ViewModelProvider.Factory delegateFactory) {
55     return EntryPoints.get(activity, ActivityEntryPoint.class)
56         .getHiltInternalFactoryFactory()
57         .fromActivity(activity, delegateFactory);
58   }
59 
60   /**
61    * Retrieves the default view model factory for the activity.
62    *
63    * <p>Do not use except in Hilt generated code!
64    */
getFragmentFactory( Fragment fragment, ViewModelProvider.Factory delegateFactory)65   public static ViewModelProvider.Factory getFragmentFactory(
66       Fragment fragment, ViewModelProvider.Factory delegateFactory) {
67     return EntryPoints.get(fragment, FragmentEntryPoint.class)
68         .getHiltInternalFactoryFactory()
69         .fromFragment(fragment, delegateFactory);
70   }
71 
72   /** Internal factory for the Hilt ViewModel Factory. */
73   public static final class InternalFactoryFactory {
74 
75     private final Application application;
76     private final Set<String> keySet;
77     private final ViewModelComponentBuilder viewModelComponentBuilder;
78 
79     @Inject
InternalFactoryFactory( Application application, @HiltViewModelMap.KeySet Set<String> keySet, ViewModelComponentBuilder viewModelComponentBuilder)80     InternalFactoryFactory(
81             Application application,
82         @HiltViewModelMap.KeySet Set<String> keySet,
83         ViewModelComponentBuilder viewModelComponentBuilder) {
84       this.application = application;
85       this.keySet = keySet;
86       this.viewModelComponentBuilder = viewModelComponentBuilder;
87     }
88 
fromActivity( ComponentActivity activity, ViewModelProvider.Factory delegateFactory)89     ViewModelProvider.Factory fromActivity(
90         ComponentActivity activity, ViewModelProvider.Factory delegateFactory) {
91       return getHiltViewModelFactory(
92           activity,
93           activity.getIntent() != null ? activity.getIntent().getExtras() : null,
94           delegateFactory);
95     }
96 
fromFragment( Fragment fragment, ViewModelProvider.Factory delegateFactory)97     ViewModelProvider.Factory fromFragment(
98         Fragment fragment, ViewModelProvider.Factory delegateFactory) {
99       return getHiltViewModelFactory(fragment, fragment.getArguments(), delegateFactory);
100     }
101 
getHiltViewModelFactory( SavedStateRegistryOwner owner, @Nullable Bundle defaultArgs, @Nullable ViewModelProvider.Factory extensionDelegate)102     private ViewModelProvider.Factory getHiltViewModelFactory(
103         SavedStateRegistryOwner owner,
104         @Nullable Bundle defaultArgs,
105         @Nullable ViewModelProvider.Factory extensionDelegate) {
106       ViewModelProvider.Factory delegate = extensionDelegate == null
107           ? new SavedStateViewModelFactory(application, owner, defaultArgs)
108           : extensionDelegate;
109       return new HiltViewModelFactory(
110           owner, defaultArgs, keySet, delegate, viewModelComponentBuilder);
111     }
112   }
113 
114   /** The activity module to declare the optional factories. */
115   @Module
116   @InstallIn(ActivityComponent.class)
117   interface ActivityModule {
118     @Multibinds
119     @HiltViewModelMap.KeySet
viewModelKeys()120     abstract Set<String> viewModelKeys();
121   }
122 
123   /** The activity entry point to retrieve the factory. */
124   @EntryPoint
125   @InstallIn(ActivityComponent.class)
126   public interface ActivityEntryPoint {
getHiltInternalFactoryFactory()127     InternalFactoryFactory getHiltInternalFactoryFactory();
128   }
129 
130   /** The fragment entry point to retrieve the factory. */
131   @EntryPoint
132   @InstallIn(FragmentComponent.class)
133   public interface FragmentEntryPoint {
getHiltInternalFactoryFactory()134     InternalFactoryFactory getHiltInternalFactoryFactory();
135   }
136 
DefaultViewModelFactories()137   private DefaultViewModelFactories() {}
138 }
139