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.Application; 20 import android.app.Service; 21 import dagger.hilt.EntryPoint; 22 import dagger.hilt.EntryPoints; 23 import dagger.hilt.InstallIn; 24 import dagger.hilt.android.internal.builders.ServiceComponentBuilder; 25 import dagger.hilt.components.SingletonComponent; 26 import dagger.hilt.internal.GeneratedComponentManager; 27 import dagger.hilt.internal.Preconditions; 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 Service. 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 public final class ServiceComponentManager implements GeneratedComponentManager<Object> { 39 /** Entrypoint for {@link ServiceComponentBuilder}. */ 40 @EntryPoint 41 @InstallIn(SingletonComponent.class) 42 public interface ServiceComponentBuilderEntryPoint { serviceComponentBuilder()43 ServiceComponentBuilder serviceComponentBuilder(); 44 } 45 46 private final Service service; 47 private Object component; 48 ServiceComponentManager(Service service)49 public ServiceComponentManager(Service service) { 50 this.service = service; 51 } 52 53 // This isn't ever really publicly exposed on a service so it should be fine without 54 // synchronization. 55 @Override generatedComponent()56 public Object generatedComponent() { 57 if (component == null) { 58 component = createComponent(); 59 } 60 return component; 61 } 62 createComponent()63 private Object createComponent() { 64 Application application = service.getApplication(); 65 Preconditions.checkState( 66 application instanceof GeneratedComponentManager, 67 "Hilt service must be attached to an @AndroidEntryPoint Application. Found: %s", 68 application.getClass()); 69 70 return EntryPoints.get(application, ServiceComponentBuilderEntryPoint.class) 71 .serviceComponentBuilder() 72 .service(service) 73 .build(); 74 } 75 } 76