Merge "Add support for adding module in the same class annotated with @DialerRootComponent."
diff --git a/java/com/android/dialer/inject/demo/DemoDaggerApplication.java b/java/com/android/dialer/inject/demo/DemoDaggerApplication.java
index 0c13dbb..ab40eca 100644
--- a/java/com/android/dialer/inject/demo/DemoDaggerApplication.java
+++ b/java/com/android/dialer/inject/demo/DemoDaggerApplication.java
@@ -50,6 +50,6 @@
   public void onCreate() {
     super.onCreate();
 
-    DemoSubcomponent.get(this).demoObject();
+    DemoSubcomponent.get(this).demoObjects();
   }
 }
diff --git a/java/com/android/dialer/inject/demo/DemoModule.java b/java/com/android/dialer/inject/demo/DemoModule.java
index 40cd6fe..9917c7d 100644
--- a/java/com/android/dialer/inject/demo/DemoModule.java
+++ b/java/com/android/dialer/inject/demo/DemoModule.java
@@ -20,6 +20,7 @@
 import com.android.dialer.inject.InstallIn;
 import dagger.Module;
 import dagger.Provides;
+import dagger.multibindings.IntoSet;
 
 /** Module for demo dagger application. */
 @Module
@@ -29,7 +30,8 @@
   private DemoModule() {}
 
   @Provides
+  @IntoSet
   static DemoObject provide() {
-    return new DemoObject("prod");
+    return DemoObject.create("prod");
   }
 }
diff --git a/java/com/android/dialer/inject/demo/DemoObject.java b/java/com/android/dialer/inject/demo/DemoObject.java
index c6d48a1..3c38621 100644
--- a/java/com/android/dialer/inject/demo/DemoObject.java
+++ b/java/com/android/dialer/inject/demo/DemoObject.java
@@ -16,17 +16,15 @@
 
 package com.android.dialer.inject.demo;
 
+import com.google.auto.value.AutoValue;
+
 /** Object used to demonstrate dagger bindings. */
-class DemoObject {
+@AutoValue
+abstract class DemoObject {
 
-  private final String value;
+  abstract String value();
 
-  DemoObject(String value) {
-    this.value = value;
-  }
-
-  @Override
-  public String toString() {
-    return value;
+  static DemoObject create(String value) {
+    return new AutoValue_DemoObject(value);
   }
 }
diff --git a/java/com/android/dialer/inject/demo/DemoSubcomponent.java b/java/com/android/dialer/inject/demo/DemoSubcomponent.java
index ff000aa..3e4dd66 100644
--- a/java/com/android/dialer/inject/demo/DemoSubcomponent.java
+++ b/java/com/android/dialer/inject/demo/DemoSubcomponent.java
@@ -20,12 +20,13 @@
 import com.android.dialer.inject.HasRootComponent;
 import com.android.dialer.inject.IncludeInDialerRoot;
 import dagger.Subcomponent;
+import java.util.Set;
 
 /** Subcomponent for the demo dagger application. */
 @Subcomponent
 public abstract class DemoSubcomponent {
 
-  abstract DemoObject demoObject();
+  abstract Set<DemoObject> demoObjects();
 
   public static DemoSubcomponent get(Context context) {
     return ((HasComponent) ((HasRootComponent) context.getApplicationContext()).component())
diff --git a/java/com/android/dialer/rootcomponentgenerator/RootComponentGeneratingStep.java b/java/com/android/dialer/rootcomponentgenerator/RootComponentGeneratingStep.java
index 61c326a..4c4e6ee 100644
--- a/java/com/android/dialer/rootcomponentgenerator/RootComponentGeneratingStep.java
+++ b/java/com/android/dialer/rootcomponentgenerator/RootComponentGeneratingStep.java
@@ -19,6 +19,7 @@
 import static com.google.auto.common.AnnotationMirrors.getAnnotationValue;
 import static com.google.auto.common.MoreElements.getAnnotationMirror;
 import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static javax.tools.Diagnostic.Kind.ERROR;
 
 import com.android.dialer.inject.DialerRootComponent;
 import com.android.dialer.inject.DialerVariant;
@@ -61,14 +62,22 @@
 
   @Override
   public Set<? extends Class<? extends Annotation>> annotations() {
-    return ImmutableSet.of(DialerRootComponent.class);
+    return ImmutableSet.of(DialerRootComponent.class, InstallIn.class, IncludeInDialerRoot.class);
   }
 
   @Override
   public Set<? extends Element> process(
       SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
     for (Element element : elementsByAnnotation.get(DialerRootComponent.class)) {
-      generateRootComponent(MoreElements.asType(element));
+      // defer root components to the next round in case where the current build target contains
+      // elements annotated with @InstallIn. Annotation processor cannot detect metadata files
+      // generated in the same round and the metadata is accessible in the next round.
+      if (elementsByAnnotation.containsKey(InstallIn.class)
+          || elementsByAnnotation.containsKey(IncludeInDialerRoot.class)) {
+        return elementsByAnnotation.get(DialerRootComponent.class);
+      } else {
+        generateRootComponent(MoreElements.asType(element));
+      }
     }
     return Collections.emptySet();
   }
@@ -124,6 +133,15 @@
       Class<? extends Annotation> annotation, MetadataProcessor metadataProcessor) {
     PackageElement cachePackage =
         processingEnv.getElementUtils().getPackageElement(RootComponentUtils.METADATA_PACKAGE_NAME);
+    if (cachePackage == null) {
+      processingEnv
+          .getMessager()
+          .printMessage(
+              ERROR,
+              "Metadata haven't been generated! do you forget to add modules "
+                  + "or components in dependency of dialer root?");
+      return;
+    }
     for (Element element : cachePackage.getEnclosedElements()) {
       Optional<AnnotationMirror> metadataAnnotation =
           getAnnotationMirror(element, RootComponentGeneratorMetadata.class);