• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.managers;
18 
19 import android.app.Activity;
20 import android.app.Application;
21 import androidx.activity.ComponentActivity;
22 import dagger.hilt.EntryPoint;
23 import dagger.hilt.EntryPoints;
24 import dagger.hilt.InstallIn;
25 import dagger.hilt.android.components.ActivityRetainedComponent;
26 import dagger.hilt.android.internal.builders.ActivityComponentBuilder;
27 import dagger.hilt.internal.GeneratedComponentManager;
28 
29 /**
30  * Do not use except in Hilt generated code!
31  *
32  * <p>A manager for the creation of components that live in the Activity.
33  *
34  * <p>Note: This class is not typed since its type in generated code is always <?> or <Object>. This
35  * is mainly due to the fact that we don't know the components at the time of generation, and
36  * because even the injector interface type is not a valid type if we have a hilt base class.
37  *
38  */
39 public class ActivityComponentManager implements GeneratedComponentManager<Object> {
40   /** Entrypoint for {@link ActivityComponentBuilder}. */
41   @EntryPoint
42   @InstallIn(ActivityRetainedComponent.class)
43   public interface ActivityComponentBuilderEntryPoint {
activityComponentBuilder()44     ActivityComponentBuilder activityComponentBuilder();
45   }
46 
47   private volatile Object component;
48   private final Object componentLock = new Object();
49 
50   protected final Activity activity;
51 
52   private final GeneratedComponentManager<ActivityRetainedComponent>
53       activityRetainedComponentManager;
54 
ActivityComponentManager(Activity activity)55   public ActivityComponentManager(Activity activity) {
56     this.activity = activity;
57     this.activityRetainedComponentManager =
58         new ActivityRetainedComponentManager((ComponentActivity) activity);
59   }
60 
61   @Override
generatedComponent()62   public Object generatedComponent() {
63     if (component == null) {
64       synchronized (componentLock) {
65         if (component == null) {
66           component = createComponent();
67         }
68       }
69     }
70     return component;
71   }
72 
createComponent()73   protected Object createComponent() {
74     if (!(activity.getApplication() instanceof GeneratedComponentManager)) {
75       if (Application.class.equals(activity.getApplication().getClass())) {
76         throw new IllegalStateException(
77                 "Hilt Activity must be attached to an @HiltAndroidApp Application. "
78                 + "Did you forget to specify your Application's class name in your manifest's "
79                 + "<application />'s android:name attribute?");
80       }
81       throw new IllegalStateException(
82               "Hilt Activity must be attached to an @AndroidEntryPoint Application. Found: "
83               + activity.getApplication().getClass());
84     }
85 
86     return EntryPoints.get(
87             activityRetainedComponentManager, ActivityComponentBuilderEntryPoint.class)
88         .activityComponentBuilder()
89         .activity(activity)
90         .build();
91   }
92 }
93