Merge "Make clipboard overlay always nonfocusable"
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 535d6a2..b1f0b54 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -2164,7 +2164,7 @@
     method @Nullable public android.net.Uri getSliceUri();
     method @NonNull public String getSmartspaceTargetId();
     method @Nullable public String getSourceNotificationKey();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData getTemplateData();
+    method @Nullable public android.app.smartspace.uitemplatedata.BaseTemplateData getTemplateData();
     method @NonNull public android.os.UserHandle getUserHandle();
     method @Nullable public android.appwidget.AppWidgetProviderInfo getWidget();
     method public boolean isSensitive();
@@ -2221,7 +2221,7 @@
     method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setShouldShowExpanded(boolean);
     method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setSliceUri(@NonNull android.net.Uri);
     method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setSourceNotificationKey(@NonNull String);
-    method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setTemplateData(@Nullable android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData);
+    method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setTemplateData(@Nullable android.app.smartspace.uitemplatedata.BaseTemplateData);
     method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setWidget(@NonNull android.appwidget.AppWidgetProviderInfo);
   }
 
@@ -2252,156 +2252,156 @@
 
 package android.app.smartspace.uitemplatedata {
 
-  public final class SmartspaceCarouselUiTemplateData extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData {
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceTapAction getCarouselAction();
-    method @NonNull public java.util.List<android.app.smartspace.uitemplatedata.SmartspaceCarouselUiTemplateData.CarouselItem> getCarouselItems();
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SmartspaceCarouselUiTemplateData> CREATOR;
-  }
-
-  public static final class SmartspaceCarouselUiTemplateData.Builder extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder {
-    ctor public SmartspaceCarouselUiTemplateData.Builder(@NonNull java.util.List<android.app.smartspace.uitemplatedata.SmartspaceCarouselUiTemplateData.CarouselItem>);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceCarouselUiTemplateData build();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceCarouselUiTemplateData.Builder setCarouselAction(@NonNull android.app.smartspace.uitemplatedata.SmartspaceTapAction);
-  }
-
-  public static final class SmartspaceCarouselUiTemplateData.CarouselItem implements android.os.Parcelable {
+  public class BaseTemplateData implements android.os.Parcelable {
     method public int describeContents();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceIcon getImage();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceText getLowerText();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceTapAction getTapAction();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceText getUpperText();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SmartspaceCarouselUiTemplateData.CarouselItem> CREATOR;
-  }
-
-  public static final class SmartspaceCarouselUiTemplateData.CarouselItem.Builder {
-    ctor public SmartspaceCarouselUiTemplateData.CarouselItem.Builder();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceCarouselUiTemplateData.CarouselItem build();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceCarouselUiTemplateData.CarouselItem.Builder setImage(@Nullable android.app.smartspace.uitemplatedata.SmartspaceIcon);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceCarouselUiTemplateData.CarouselItem.Builder setLowerText(@Nullable android.app.smartspace.uitemplatedata.SmartspaceText);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceCarouselUiTemplateData.CarouselItem.Builder setTapAction(@Nullable android.app.smartspace.uitemplatedata.SmartspaceTapAction);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceCarouselUiTemplateData.CarouselItem.Builder setUpperText(@Nullable android.app.smartspace.uitemplatedata.SmartspaceText);
-  }
-
-  public final class SmartspaceCombinedCardsUiTemplateData extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData {
-    method @NonNull public java.util.List<android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData> getCombinedCardDataList();
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SmartspaceCombinedCardsUiTemplateData> CREATOR;
-  }
-
-  public static final class SmartspaceCombinedCardsUiTemplateData.Builder extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder {
-    ctor public SmartspaceCombinedCardsUiTemplateData.Builder(@NonNull java.util.List<android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData>);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceCombinedCardsUiTemplateData build();
-  }
-
-  public class SmartspaceDefaultUiTemplateData implements android.os.Parcelable {
-    method public int describeContents();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceTapAction getPrimaryTapAction();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceIcon getSubtitleIcon();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceText getSubtitleText();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceText getSupplementalAlarmText();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceIcon getSupplementalSubtitleIcon();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceTapAction getSupplementalSubtitleTapAction();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceText getSupplementalSubtitleText();
+    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getPrimaryTapAction();
+    method @Nullable public android.app.smartspace.uitemplatedata.Icon getSubtitleIcon();
+    method @Nullable public android.app.smartspace.uitemplatedata.Text getSubtitleText();
+    method @Nullable public android.app.smartspace.uitemplatedata.Text getSupplementalAlarmText();
+    method @Nullable public android.app.smartspace.uitemplatedata.Icon getSupplementalSubtitleIcon();
+    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getSupplementalSubtitleTapAction();
+    method @Nullable public android.app.smartspace.uitemplatedata.Text getSupplementalSubtitleText();
     method public int getTemplateType();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceIcon getTitleIcon();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceText getTitleText();
+    method @Nullable public android.app.smartspace.uitemplatedata.Icon getTitleIcon();
+    method @Nullable public android.app.smartspace.uitemplatedata.Text getTitleText();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData> CREATOR;
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.BaseTemplateData> CREATOR;
   }
 
-  public static class SmartspaceDefaultUiTemplateData.Builder {
-    ctor public SmartspaceDefaultUiTemplateData.Builder(int);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData build();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder setPrimaryTapAction(@NonNull android.app.smartspace.uitemplatedata.SmartspaceTapAction);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder setSubtitleIcon(@NonNull android.app.smartspace.uitemplatedata.SmartspaceIcon);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder setSubtitleText(@NonNull android.app.smartspace.uitemplatedata.SmartspaceText);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder setSupplementalAlarmText(@NonNull android.app.smartspace.uitemplatedata.SmartspaceText);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder setSupplementalSubtitleIcon(@NonNull android.app.smartspace.uitemplatedata.SmartspaceIcon);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder setSupplementalSubtitleTapAction(@NonNull android.app.smartspace.uitemplatedata.SmartspaceTapAction);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder setSupplementalSubtitleText(@NonNull android.app.smartspace.uitemplatedata.SmartspaceText);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder setTitleIcon(@NonNull android.app.smartspace.uitemplatedata.SmartspaceIcon);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder setTitleText(@NonNull android.app.smartspace.uitemplatedata.SmartspaceText);
+  public static class BaseTemplateData.Builder {
+    ctor public BaseTemplateData.Builder(int);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData build();
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setPrimaryTapAction(@NonNull android.app.smartspace.uitemplatedata.TapAction);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSubtitleIcon(@NonNull android.app.smartspace.uitemplatedata.Icon);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSubtitleText(@NonNull android.app.smartspace.uitemplatedata.Text);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalAlarmText(@NonNull android.app.smartspace.uitemplatedata.Text);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalSubtitleIcon(@NonNull android.app.smartspace.uitemplatedata.Icon);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalSubtitleTapAction(@NonNull android.app.smartspace.uitemplatedata.TapAction);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalSubtitleText(@NonNull android.app.smartspace.uitemplatedata.Text);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setTitleIcon(@NonNull android.app.smartspace.uitemplatedata.Icon);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setTitleText(@NonNull android.app.smartspace.uitemplatedata.Text);
   }
 
-  public final class SmartspaceHeadToHeadUiTemplateData extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData {
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceTapAction getHeadToHeadAction();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceIcon getHeadToHeadFirstCompetitorIcon();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceText getHeadToHeadFirstCompetitorText();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceIcon getHeadToHeadSecondCompetitorIcon();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceText getHeadToHeadSecondCompetitorText();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceText getHeadToHeadTitle();
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SmartspaceHeadToHeadUiTemplateData> CREATOR;
+  public final class CarouselTemplateData extends android.app.smartspace.uitemplatedata.BaseTemplateData {
+    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getCarouselAction();
+    method @NonNull public java.util.List<android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem> getCarouselItems();
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.CarouselTemplateData> CREATOR;
   }
 
-  public static final class SmartspaceHeadToHeadUiTemplateData.Builder extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder {
-    ctor public SmartspaceHeadToHeadUiTemplateData.Builder();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceHeadToHeadUiTemplateData build();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceHeadToHeadUiTemplateData.Builder setHeadToHeadAction(@Nullable android.app.smartspace.uitemplatedata.SmartspaceTapAction);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceHeadToHeadUiTemplateData.Builder setHeadToHeadFirstCompetitorIcon(@Nullable android.app.smartspace.uitemplatedata.SmartspaceIcon);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceHeadToHeadUiTemplateData.Builder setHeadToHeadFirstCompetitorText(@Nullable android.app.smartspace.uitemplatedata.SmartspaceText);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceHeadToHeadUiTemplateData.Builder setHeadToHeadSecondCompetitorIcon(@Nullable android.app.smartspace.uitemplatedata.SmartspaceIcon);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceHeadToHeadUiTemplateData.Builder setHeadToHeadSecondCompetitorText(@Nullable android.app.smartspace.uitemplatedata.SmartspaceText);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceHeadToHeadUiTemplateData.Builder setHeadToHeadTitle(@Nullable android.app.smartspace.uitemplatedata.SmartspaceText);
+  public static final class CarouselTemplateData.Builder extends android.app.smartspace.uitemplatedata.BaseTemplateData.Builder {
+    ctor public CarouselTemplateData.Builder(@NonNull java.util.List<android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem>);
+    method @NonNull public android.app.smartspace.uitemplatedata.CarouselTemplateData build();
+    method @NonNull public android.app.smartspace.uitemplatedata.CarouselTemplateData.Builder setCarouselAction(@NonNull android.app.smartspace.uitemplatedata.TapAction);
   }
 
-  public final class SmartspaceIcon implements android.os.Parcelable {
+  public static final class CarouselTemplateData.CarouselItem implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.app.smartspace.uitemplatedata.Icon getImage();
+    method @Nullable public android.app.smartspace.uitemplatedata.Text getLowerText();
+    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getTapAction();
+    method @Nullable public android.app.smartspace.uitemplatedata.Text getUpperText();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem> CREATOR;
+  }
+
+  public static final class CarouselTemplateData.CarouselItem.Builder {
+    ctor public CarouselTemplateData.CarouselItem.Builder();
+    method @NonNull public android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem build();
+    method @NonNull public android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem.Builder setImage(@Nullable android.app.smartspace.uitemplatedata.Icon);
+    method @NonNull public android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem.Builder setLowerText(@Nullable android.app.smartspace.uitemplatedata.Text);
+    method @NonNull public android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem.Builder setTapAction(@Nullable android.app.smartspace.uitemplatedata.TapAction);
+    method @NonNull public android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem.Builder setUpperText(@Nullable android.app.smartspace.uitemplatedata.Text);
+  }
+
+  public final class CombinedCardsTemplateData extends android.app.smartspace.uitemplatedata.BaseTemplateData {
+    method @NonNull public java.util.List<android.app.smartspace.uitemplatedata.BaseTemplateData> getCombinedCardDataList();
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.CombinedCardsTemplateData> CREATOR;
+  }
+
+  public static final class CombinedCardsTemplateData.Builder extends android.app.smartspace.uitemplatedata.BaseTemplateData.Builder {
+    ctor public CombinedCardsTemplateData.Builder(@NonNull java.util.List<android.app.smartspace.uitemplatedata.BaseTemplateData>);
+    method @NonNull public android.app.smartspace.uitemplatedata.CombinedCardsTemplateData build();
+  }
+
+  public final class HeadToHeadTemplateData extends android.app.smartspace.uitemplatedata.BaseTemplateData {
+    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getHeadToHeadAction();
+    method @Nullable public android.app.smartspace.uitemplatedata.Icon getHeadToHeadFirstCompetitorIcon();
+    method @Nullable public android.app.smartspace.uitemplatedata.Text getHeadToHeadFirstCompetitorText();
+    method @Nullable public android.app.smartspace.uitemplatedata.Icon getHeadToHeadSecondCompetitorIcon();
+    method @Nullable public android.app.smartspace.uitemplatedata.Text getHeadToHeadSecondCompetitorText();
+    method @Nullable public android.app.smartspace.uitemplatedata.Text getHeadToHeadTitle();
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.HeadToHeadTemplateData> CREATOR;
+  }
+
+  public static final class HeadToHeadTemplateData.Builder extends android.app.smartspace.uitemplatedata.BaseTemplateData.Builder {
+    ctor public HeadToHeadTemplateData.Builder();
+    method @NonNull public android.app.smartspace.uitemplatedata.HeadToHeadTemplateData build();
+    method @NonNull public android.app.smartspace.uitemplatedata.HeadToHeadTemplateData.Builder setHeadToHeadAction(@Nullable android.app.smartspace.uitemplatedata.TapAction);
+    method @NonNull public android.app.smartspace.uitemplatedata.HeadToHeadTemplateData.Builder setHeadToHeadFirstCompetitorIcon(@Nullable android.app.smartspace.uitemplatedata.Icon);
+    method @NonNull public android.app.smartspace.uitemplatedata.HeadToHeadTemplateData.Builder setHeadToHeadFirstCompetitorText(@Nullable android.app.smartspace.uitemplatedata.Text);
+    method @NonNull public android.app.smartspace.uitemplatedata.HeadToHeadTemplateData.Builder setHeadToHeadSecondCompetitorIcon(@Nullable android.app.smartspace.uitemplatedata.Icon);
+    method @NonNull public android.app.smartspace.uitemplatedata.HeadToHeadTemplateData.Builder setHeadToHeadSecondCompetitorText(@Nullable android.app.smartspace.uitemplatedata.Text);
+    method @NonNull public android.app.smartspace.uitemplatedata.HeadToHeadTemplateData.Builder setHeadToHeadTitle(@Nullable android.app.smartspace.uitemplatedata.Text);
+  }
+
+  public final class Icon implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public CharSequence getContentDescription();
     method @NonNull public android.graphics.drawable.Icon getIcon();
     method public boolean shouldTint();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SmartspaceIcon> CREATOR;
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.Icon> CREATOR;
   }
 
-  public static final class SmartspaceIcon.Builder {
-    ctor public SmartspaceIcon.Builder(@NonNull android.graphics.drawable.Icon);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceIcon build();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceIcon.Builder setContentDescription(@NonNull CharSequence);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceIcon.Builder setShouldTint(boolean);
+  public static final class Icon.Builder {
+    ctor public Icon.Builder(@NonNull android.graphics.drawable.Icon);
+    method @NonNull public android.app.smartspace.uitemplatedata.Icon build();
+    method @NonNull public android.app.smartspace.uitemplatedata.Icon.Builder setContentDescription(@NonNull CharSequence);
+    method @NonNull public android.app.smartspace.uitemplatedata.Icon.Builder setShouldTint(boolean);
   }
 
-  public final class SmartspaceSubCardUiTemplateData extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData {
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceTapAction getSubCardAction();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceIcon getSubCardIcon();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceText getSubCardText();
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SmartspaceSubCardUiTemplateData> CREATOR;
+  public final class SubCardTemplateData extends android.app.smartspace.uitemplatedata.BaseTemplateData {
+    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getSubCardAction();
+    method @NonNull public android.app.smartspace.uitemplatedata.Icon getSubCardIcon();
+    method @Nullable public android.app.smartspace.uitemplatedata.Text getSubCardText();
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SubCardTemplateData> CREATOR;
   }
 
-  public static final class SmartspaceSubCardUiTemplateData.Builder extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder {
-    ctor public SmartspaceSubCardUiTemplateData.Builder(@NonNull android.app.smartspace.uitemplatedata.SmartspaceIcon);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceSubCardUiTemplateData build();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceSubCardUiTemplateData.Builder setSubCardAction(@NonNull android.app.smartspace.uitemplatedata.SmartspaceTapAction);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceSubCardUiTemplateData.Builder setSubCardText(@NonNull android.app.smartspace.uitemplatedata.SmartspaceText);
+  public static final class SubCardTemplateData.Builder extends android.app.smartspace.uitemplatedata.BaseTemplateData.Builder {
+    ctor public SubCardTemplateData.Builder(@NonNull android.app.smartspace.uitemplatedata.Icon);
+    method @NonNull public android.app.smartspace.uitemplatedata.SubCardTemplateData build();
+    method @NonNull public android.app.smartspace.uitemplatedata.SubCardTemplateData.Builder setSubCardAction(@NonNull android.app.smartspace.uitemplatedata.TapAction);
+    method @NonNull public android.app.smartspace.uitemplatedata.SubCardTemplateData.Builder setSubCardText(@NonNull android.app.smartspace.uitemplatedata.Text);
   }
 
-  public final class SmartspaceSubImageUiTemplateData extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData {
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceTapAction getSubImageAction();
-    method @NonNull public java.util.List<android.app.smartspace.uitemplatedata.SmartspaceText> getSubImageTexts();
-    method @NonNull public java.util.List<android.app.smartspace.uitemplatedata.SmartspaceIcon> getSubImages();
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SmartspaceSubImageUiTemplateData> CREATOR;
+  public final class SubImageTemplateData extends android.app.smartspace.uitemplatedata.BaseTemplateData {
+    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getSubImageAction();
+    method @NonNull public java.util.List<android.app.smartspace.uitemplatedata.Text> getSubImageTexts();
+    method @NonNull public java.util.List<android.app.smartspace.uitemplatedata.Icon> getSubImages();
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SubImageTemplateData> CREATOR;
   }
 
-  public static final class SmartspaceSubImageUiTemplateData.Builder extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder {
-    ctor public SmartspaceSubImageUiTemplateData.Builder(@NonNull java.util.List<android.app.smartspace.uitemplatedata.SmartspaceText>, @NonNull java.util.List<android.app.smartspace.uitemplatedata.SmartspaceIcon>);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceSubImageUiTemplateData build();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceSubImageUiTemplateData.Builder setSubImageAction(@NonNull android.app.smartspace.uitemplatedata.SmartspaceTapAction);
+  public static final class SubImageTemplateData.Builder extends android.app.smartspace.uitemplatedata.BaseTemplateData.Builder {
+    ctor public SubImageTemplateData.Builder(@NonNull java.util.List<android.app.smartspace.uitemplatedata.Text>, @NonNull java.util.List<android.app.smartspace.uitemplatedata.Icon>);
+    method @NonNull public android.app.smartspace.uitemplatedata.SubImageTemplateData build();
+    method @NonNull public android.app.smartspace.uitemplatedata.SubImageTemplateData.Builder setSubImageAction(@NonNull android.app.smartspace.uitemplatedata.TapAction);
   }
 
-  public final class SmartspaceSubListUiTemplateData extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData {
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceTapAction getSubListAction();
-    method @Nullable public android.app.smartspace.uitemplatedata.SmartspaceIcon getSubListIcon();
-    method @NonNull public java.util.List<android.app.smartspace.uitemplatedata.SmartspaceText> getSubListTexts();
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SmartspaceSubListUiTemplateData> CREATOR;
+  public final class SubListTemplateData extends android.app.smartspace.uitemplatedata.BaseTemplateData {
+    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getSubListAction();
+    method @Nullable public android.app.smartspace.uitemplatedata.Icon getSubListIcon();
+    method @NonNull public java.util.List<android.app.smartspace.uitemplatedata.Text> getSubListTexts();
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SubListTemplateData> CREATOR;
   }
 
-  public static final class SmartspaceSubListUiTemplateData.Builder extends android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData.Builder {
-    ctor public SmartspaceSubListUiTemplateData.Builder(@NonNull java.util.List<android.app.smartspace.uitemplatedata.SmartspaceText>);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceSubListUiTemplateData build();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceSubListUiTemplateData.Builder setSubListAction(@NonNull android.app.smartspace.uitemplatedata.SmartspaceTapAction);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceSubListUiTemplateData.Builder setSubListIcon(@NonNull android.app.smartspace.uitemplatedata.SmartspaceIcon);
+  public static final class SubListTemplateData.Builder extends android.app.smartspace.uitemplatedata.BaseTemplateData.Builder {
+    ctor public SubListTemplateData.Builder(@NonNull java.util.List<android.app.smartspace.uitemplatedata.Text>);
+    method @NonNull public android.app.smartspace.uitemplatedata.SubListTemplateData build();
+    method @NonNull public android.app.smartspace.uitemplatedata.SubListTemplateData.Builder setSubListAction(@NonNull android.app.smartspace.uitemplatedata.TapAction);
+    method @NonNull public android.app.smartspace.uitemplatedata.SubListTemplateData.Builder setSubListIcon(@NonNull android.app.smartspace.uitemplatedata.Icon);
   }
 
-  public final class SmartspaceTapAction implements android.os.Parcelable {
+  public final class TapAction implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public android.os.Bundle getExtras();
     method @Nullable public CharSequence getId();
@@ -2409,31 +2409,33 @@
     method @Nullable public android.app.PendingIntent getPendingIntent();
     method @Nullable public android.os.UserHandle getUserHandle();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SmartspaceTapAction> CREATOR;
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.TapAction> CREATOR;
   }
 
-  public static final class SmartspaceTapAction.Builder {
-    ctor public SmartspaceTapAction.Builder(@NonNull CharSequence);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceTapAction build();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceTapAction.Builder setExtras(@NonNull android.os.Bundle);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceTapAction.Builder setIntent(@NonNull android.content.Intent);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceTapAction.Builder setPendingIntent(@NonNull android.app.PendingIntent);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceTapAction.Builder setUserHandle(@Nullable android.os.UserHandle);
+  public static final class TapAction.Builder {
+    ctor public TapAction.Builder(@NonNull CharSequence);
+    method @NonNull public android.app.smartspace.uitemplatedata.TapAction build();
+    method @NonNull public android.app.smartspace.uitemplatedata.TapAction.Builder setExtras(@NonNull android.os.Bundle);
+    method @NonNull public android.app.smartspace.uitemplatedata.TapAction.Builder setIntent(@NonNull android.content.Intent);
+    method @NonNull public android.app.smartspace.uitemplatedata.TapAction.Builder setPendingIntent(@NonNull android.app.PendingIntent);
+    method @NonNull public android.app.smartspace.uitemplatedata.TapAction.Builder setUserHandle(@Nullable android.os.UserHandle);
   }
 
-  public final class SmartspaceText implements android.os.Parcelable {
+  public final class Text implements android.os.Parcelable {
     method public int describeContents();
+    method public int getMaxLines();
     method @NonNull public CharSequence getText();
     method @NonNull public android.text.TextUtils.TruncateAt getTruncateAtType();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.SmartspaceText> CREATOR;
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.Text> CREATOR;
   }
 
-  public static final class SmartspaceText.Builder {
-    ctor public SmartspaceText.Builder(@NonNull CharSequence);
-    ctor public SmartspaceText.Builder(@NonNull CharSequence, @NonNull android.text.TextUtils.TruncateAt);
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceText build();
-    method @NonNull public android.app.smartspace.uitemplatedata.SmartspaceText.Builder setTruncateAtType(@NonNull android.text.TextUtils.TruncateAt);
+  public static final class Text.Builder {
+    ctor public Text.Builder(@NonNull CharSequence);
+    ctor public Text.Builder(@NonNull CharSequence, @NonNull android.text.TextUtils.TruncateAt);
+    method @NonNull public android.app.smartspace.uitemplatedata.Text build();
+    method @NonNull public android.app.smartspace.uitemplatedata.Text.Builder setMaxLines(int);
+    method @NonNull public android.app.smartspace.uitemplatedata.Text.Builder setTruncateAtType(@NonNull android.text.TextUtils.TruncateAt);
   }
 
 }
@@ -2745,7 +2747,7 @@
 package android.companion.virtual {
 
   public final class VirtualDeviceManager {
-    method @Nullable @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.companion.virtual.VirtualDeviceManager.VirtualDevice createVirtualDevice(int, @NonNull android.companion.virtual.VirtualDeviceParams);
+    method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.companion.virtual.VirtualDeviceManager.VirtualDevice createVirtualDevice(int, @NonNull android.companion.virtual.VirtualDeviceParams);
   }
 
   public static interface VirtualDeviceManager.ActivityListener {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 84b393a..5c5321c 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1200,7 +1200,6 @@
     field public static final int SWITCHING_TYPE_NONE = 0; // 0x0
     field public static final int SWITCHING_TYPE_WITHIN_GROUPS = 1; // 0x1
     field public static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 512; // 0x200
-    field public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1024; // 0x400
   }
 
 }
diff --git a/core/java/android/app/smartspace/SmartspaceTarget.java b/core/java/android/app/smartspace/SmartspaceTarget.java
index 78f51be..fd7088f 100644
--- a/core/java/android/app/smartspace/SmartspaceTarget.java
+++ b/core/java/android/app/smartspace/SmartspaceTarget.java
@@ -20,7 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
-import android.app.smartspace.uitemplatedata.SmartspaceDefaultUiTemplateData;
+import android.app.smartspace.uitemplatedata.BaseTemplateData;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.net.Uri;
@@ -133,7 +133,7 @@
     private final AppWidgetProviderInfo mWidget;
 
     @Nullable
-    private final SmartspaceDefaultUiTemplateData mTemplateData;
+    private final BaseTemplateData mTemplateData;
 
     public static final int FEATURE_UNDEFINED = 0;
     public static final int FEATURE_WEATHER = 1;
@@ -194,15 +194,25 @@
     }
 
     public static final int UI_TEMPLATE_UNDEFINED = 0;
+    // Default template whose data is represented by {@link BaseTemplateData}. The default
+    // template is also a base card for the other types of templates.
     public static final int UI_TEMPLATE_DEFAULT = 1;
+    // Sub-image template whose data is represented by {@link SubImageTemplateData}
     public static final int UI_TEMPLATE_SUB_IMAGE = 2;
+    // Sub-list template whose data is represented by {@link SubListTemplateData}
     public static final int UI_TEMPLATE_SUB_LIST = 3;
+    // Carousel template whose data is represented by {@link CarouselTemplateData}
     public static final int UI_TEMPLATE_CAROUSEL = 4;
+    // Head-to-head template whose data is represented by {@link HeadToHeadTemplateData}
     public static final int UI_TEMPLATE_HEAD_TO_HEAD = 5;
+    // Combined-cards template whose data is represented by {@link CombinedCardsTemplateData}
     public static final int UI_TEMPLATE_COMBINED_CARDS = 6;
+    // Sub-card template whose data is represented by {@link SubCardTemplateData}
     public static final int UI_TEMPLATE_SUB_CARD = 7;
 
     /**
+     * The types of the Smartspace ui templates.
+     *
      * @hide
      */
     @IntDef(prefix = {"UI_TEMPLATE_"}, value = {
@@ -237,7 +247,7 @@
         this.mAssociatedSmartspaceTargetId = in.readString();
         this.mSliceUri = in.readTypedObject(Uri.CREATOR);
         this.mWidget = in.readTypedObject(AppWidgetProviderInfo.CREATOR);
-        this.mTemplateData = in.readTypedObject(SmartspaceDefaultUiTemplateData.CREATOR);
+        this.mTemplateData = in.readTypedObject(BaseTemplateData.CREATOR);
     }
 
     private SmartspaceTarget(String smartspaceTargetId,
@@ -248,7 +258,7 @@
             boolean shouldShowExpanded, String sourceNotificationKey,
             ComponentName componentName, UserHandle userHandle,
             String associatedSmartspaceTargetId, Uri sliceUri,
-            AppWidgetProviderInfo widget, SmartspaceDefaultUiTemplateData templateData) {
+            AppWidgetProviderInfo widget, BaseTemplateData templateData) {
         mSmartspaceTargetId = smartspaceTargetId;
         mHeaderAction = headerAction;
         mBaseAction = baseAction;
@@ -406,7 +416,7 @@
      * Returns the UI template data.
      */
     @Nullable
-    public SmartspaceDefaultUiTemplateData getTemplateData() {
+    public BaseTemplateData getTemplateData() {
         return mTemplateData;
     }
 
@@ -536,7 +546,7 @@
         private String mAssociatedSmartspaceTargetId;
         private Uri mSliceUri;
         private AppWidgetProviderInfo mWidget;
-        private SmartspaceDefaultUiTemplateData mTemplateData;
+        private BaseTemplateData mTemplateData;
 
         /**
          * A builder for {@link SmartspaceTarget}.
@@ -689,7 +699,7 @@
          */
         @NonNull
         public Builder setTemplateData(
-                @Nullable SmartspaceDefaultUiTemplateData templateData) {
+                @Nullable BaseTemplateData templateData) {
             mTemplateData = templateData;
             return this;
         }
diff --git a/core/java/android/app/smartspace/SmartspaceUtils.java b/core/java/android/app/smartspace/SmartspaceUtils.java
index 4545f43..cad4453 100644
--- a/core/java/android/app/smartspace/SmartspaceUtils.java
+++ b/core/java/android/app/smartspace/SmartspaceUtils.java
@@ -17,7 +17,7 @@
 package android.app.smartspace;
 
 import android.annotation.Nullable;
-import android.app.smartspace.uitemplatedata.SmartspaceText;
+import android.app.smartspace.uitemplatedata.Text;
 import android.text.TextUtils;
 
 /**
@@ -30,13 +30,13 @@
     private SmartspaceUtils() {
     }
 
-    /** Returns true if the passed in {@link SmartspaceText} is null or its content is empty. */
-    public static boolean isEmpty(@Nullable SmartspaceText text) {
+    /** Returns true if the passed in {@link Text} is null or its content is empty. */
+    public static boolean isEmpty(@Nullable Text text) {
         return text == null || TextUtils.isEmpty(text.getText());
     }
 
-    /** Returns true if the passed-in {@link SmartspaceText}s are equal. */
-    public static boolean isEqual(@Nullable SmartspaceText text1, @Nullable SmartspaceText text2) {
+    /** Returns true if the passed-in {@link Text}s are equal. */
+    public static boolean isEqual(@Nullable Text text1, @Nullable Text text2) {
         if (text1 == null && text2 == null) return true;
         if (text1 == null || text2 == null) return false;
         return text1.equals(text2);
diff --git a/core/java/android/app/smartspace/uitemplatedata/SmartspaceDefaultUiTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/BaseTemplateData.java
similarity index 69%
rename from core/java/android/app/smartspace/uitemplatedata/SmartspaceDefaultUiTemplateData.java
rename to core/java/android/app/smartspace/uitemplatedata/BaseTemplateData.java
index a7ac9c7..a07af68 100644
--- a/core/java/android/app/smartspace/uitemplatedata/SmartspaceDefaultUiTemplateData.java
+++ b/core/java/android/app/smartspace/uitemplatedata/BaseTemplateData.java
@@ -29,12 +29,19 @@
 
 /**
  * Holds all the relevant data needed to render a Smartspace card with the default Ui Template.
+ * <ul>
+ *     <li> title_text (may contain a start drawable) </li>
+ *     <li> subtitle_text (may contain a start drawable) . supplemental_subtitle_text (may
+ *     contain a start drawable) </li>
+ *     <li> next_alarm_text (contain a start drawable) + supplemental_alarm_text .
+ *     do_not_disturb_view </li>
+ * </ul>
  *
  * @hide
  */
 @SystemApi
 @SuppressLint("ParcelNotFinal")
-public class SmartspaceDefaultUiTemplateData implements Parcelable {
+public class BaseTemplateData implements Parcelable {
 
     /**
      * {@link UiTemplateType} indicating the template type of this template data.
@@ -49,17 +56,17 @@
      * will be used, which has its own tap action applied to the title area.
      */
     @Nullable
-    private final SmartspaceText mTitleText;
+    private final Text mTitleText;
 
     @Nullable
-    private final SmartspaceIcon mTitleIcon;
+    private final Icon mTitleIcon;
 
     /** Subtitle text and icon are shown at the second row. */
     @Nullable
-    private final SmartspaceText mSubtitleText;
+    private final Text mSubtitleText;
 
     @Nullable
-    private final SmartspaceIcon mSubtitleIcon;
+    private final Icon mSubtitleIcon;
 
     /**
      * Primary tap action for the entire card, including the blank spaces, except: 1. When title is
@@ -67,59 +74,59 @@
      * action if being set; 3. Secondary card uses its own tap action if being set.
      */
     @Nullable
-    private final SmartspaceTapAction mPrimaryTapAction;
+    private final TapAction mPrimaryTapAction;
 
     /**
      * Supplemental subtitle text and icon are shown at the second row following the subtitle text.
      * Mainly used for weather info on non-weather card.
      */
     @Nullable
-    private final SmartspaceText mSupplementalSubtitleText;
+    private final Text mSupplementalSubtitleText;
 
     @Nullable
-    private final SmartspaceIcon mSupplementalSubtitleIcon;
+    private final Icon mSupplementalSubtitleIcon;
 
     /**
      * Tap action for the supplemental subtitle's text and icon. Will use the primary tap action if
      * not being set.
      */
     @Nullable
-    private final SmartspaceTapAction mSupplementalSubtitleTapAction;
+    private final TapAction mSupplementalSubtitleTapAction;
 
     /**
      * Supplemental alarm text is specifically used for holiday alarm, which is appended to "next
      * alarm".
      */
     @Nullable
-    private final SmartspaceText mSupplementalAlarmText;
+    private final Text mSupplementalAlarmText;
 
-    SmartspaceDefaultUiTemplateData(@NonNull Parcel in) {
+    BaseTemplateData(@NonNull Parcel in) {
         mTemplateType = in.readInt();
-        mTitleText = in.readTypedObject(SmartspaceText.CREATOR);
-        mTitleIcon = in.readTypedObject(SmartspaceIcon.CREATOR);
-        mSubtitleText = in.readTypedObject(SmartspaceText.CREATOR);
-        mSubtitleIcon = in.readTypedObject(SmartspaceIcon.CREATOR);
-        mPrimaryTapAction = in.readTypedObject(SmartspaceTapAction.CREATOR);
-        mSupplementalSubtitleText = in.readTypedObject(SmartspaceText.CREATOR);
-        mSupplementalSubtitleIcon = in.readTypedObject(SmartspaceIcon.CREATOR);
-        mSupplementalSubtitleTapAction = in.readTypedObject(SmartspaceTapAction.CREATOR);
-        mSupplementalAlarmText = in.readTypedObject(SmartspaceText.CREATOR);
+        mTitleText = in.readTypedObject(Text.CREATOR);
+        mTitleIcon = in.readTypedObject(Icon.CREATOR);
+        mSubtitleText = in.readTypedObject(Text.CREATOR);
+        mSubtitleIcon = in.readTypedObject(Icon.CREATOR);
+        mPrimaryTapAction = in.readTypedObject(TapAction.CREATOR);
+        mSupplementalSubtitleText = in.readTypedObject(Text.CREATOR);
+        mSupplementalSubtitleIcon = in.readTypedObject(Icon.CREATOR);
+        mSupplementalSubtitleTapAction = in.readTypedObject(TapAction.CREATOR);
+        mSupplementalAlarmText = in.readTypedObject(Text.CREATOR);
     }
 
     /**
      * Should ONLY used by subclasses. For the general instance creation, please use
      * SmartspaceDefaultUiTemplateData.Builder.
      */
-    SmartspaceDefaultUiTemplateData(@UiTemplateType int templateType,
-            @Nullable SmartspaceText titleText,
-            @Nullable SmartspaceIcon titleIcon,
-            @Nullable SmartspaceText subtitleText,
-            @Nullable SmartspaceIcon subtitleIcon,
-            @Nullable SmartspaceTapAction primaryTapAction,
-            @Nullable SmartspaceText supplementalSubtitleText,
-            @Nullable SmartspaceIcon supplementalSubtitleIcon,
-            @Nullable SmartspaceTapAction supplementalSubtitleTapAction,
-            @Nullable SmartspaceText supplementalAlarmText) {
+    BaseTemplateData(@UiTemplateType int templateType,
+            @Nullable Text titleText,
+            @Nullable Icon titleIcon,
+            @Nullable Text subtitleText,
+            @Nullable Icon subtitleIcon,
+            @Nullable TapAction primaryTapAction,
+            @Nullable Text supplementalSubtitleText,
+            @Nullable Icon supplementalSubtitleIcon,
+            @Nullable TapAction supplementalSubtitleTapAction,
+            @Nullable Text supplementalAlarmText) {
         mTemplateType = templateType;
         mTitleText = titleText;
         mTitleIcon = titleIcon;
@@ -132,53 +139,63 @@
         mSupplementalAlarmText = supplementalAlarmText;
     }
 
+    /** Returns the template type. By default is UNDEFINED. */
     @UiTemplateType
     public int getTemplateType() {
         return mTemplateType;
     }
 
+    /** Returns the title's text. */
     @Nullable
-    public SmartspaceText getTitleText() {
+    public Text getTitleText() {
         return mTitleText;
     }
 
+    /** Returns the title's icon. */
     @Nullable
-    public SmartspaceIcon getTitleIcon() {
+    public Icon getTitleIcon() {
         return mTitleIcon;
     }
 
+    /** Returns the subtitle's text. */
     @Nullable
-    public SmartspaceText getSubtitleText() {
+    public Text getSubtitleText() {
         return mSubtitleText;
     }
 
+    /** Returns the subtitle's icon. */
     @Nullable
-    public SmartspaceIcon getSubtitleIcon() {
+    public Icon getSubtitleIcon() {
         return mSubtitleIcon;
     }
 
+    /** Returns the card's primary tap action. */
     @Nullable
-    public SmartspaceTapAction getPrimaryTapAction() {
+    public TapAction getPrimaryTapAction() {
         return mPrimaryTapAction;
     }
 
+    /** Returns the supplemental subtitle's text. */
     @Nullable
-    public SmartspaceText getSupplementalSubtitleText() {
+    public Text getSupplementalSubtitleText() {
         return mSupplementalSubtitleText;
     }
 
+    /** Returns the supplemental subtitle's icon. */
     @Nullable
-    public SmartspaceIcon getSupplementalSubtitleIcon() {
+    public Icon getSupplementalSubtitleIcon() {
         return mSupplementalSubtitleIcon;
     }
 
+    /** Returns the supplemental subtitle's tap action. Can be null if not being set. */
     @Nullable
-    public SmartspaceTapAction getSupplementalSubtitleTapAction() {
+    public TapAction getSupplementalSubtitleTapAction() {
         return mSupplementalSubtitleTapAction;
     }
 
+    /** Returns the supplemental alarm text. */
     @Nullable
-    public SmartspaceText getSupplementalAlarmText() {
+    public Text getSupplementalAlarmText() {
         return mSupplementalAlarmText;
     }
 
@@ -186,16 +203,16 @@
      * @see Parcelable.Creator
      */
     @NonNull
-    public static final Creator<SmartspaceDefaultUiTemplateData> CREATOR =
-            new Creator<SmartspaceDefaultUiTemplateData>() {
+    public static final Creator<BaseTemplateData> CREATOR =
+            new Creator<BaseTemplateData>() {
                 @Override
-                public SmartspaceDefaultUiTemplateData createFromParcel(Parcel in) {
-                    return new SmartspaceDefaultUiTemplateData(in);
+                public BaseTemplateData createFromParcel(Parcel in) {
+                    return new BaseTemplateData(in);
                 }
 
                 @Override
-                public SmartspaceDefaultUiTemplateData[] newArray(int size) {
-                    return new SmartspaceDefaultUiTemplateData[size];
+                public BaseTemplateData[] newArray(int size) {
+                    return new BaseTemplateData[size];
                 }
             };
 
@@ -221,8 +238,8 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (!(o instanceof SmartspaceDefaultUiTemplateData)) return false;
-        SmartspaceDefaultUiTemplateData that = (SmartspaceDefaultUiTemplateData) o;
+        if (!(o instanceof BaseTemplateData)) return false;
+        BaseTemplateData that = (BaseTemplateData) o;
         return mTemplateType == that.mTemplateType && SmartspaceUtils.isEqual(mTitleText,
                 that.mTitleText)
                 && Objects.equals(mTitleIcon, that.mTitleIcon)
@@ -261,7 +278,7 @@
     }
 
     /**
-     * A builder for {@link SmartspaceDefaultUiTemplateData} object.
+     * A builder for {@link BaseTemplateData} object.
      *
      * @hide
      */
@@ -270,18 +287,18 @@
     public static class Builder {
         @UiTemplateType
         private final int mTemplateType;
-        private SmartspaceText mTitleText;
-        private SmartspaceIcon mTitleIcon;
-        private SmartspaceText mSubtitleText;
-        private SmartspaceIcon mSubtitleIcon;
-        private SmartspaceTapAction mPrimaryTapAction;
-        private SmartspaceText mSupplementalSubtitleText;
-        private SmartspaceIcon mSupplementalSubtitleIcon;
-        private SmartspaceTapAction mSupplementalSubtitleTapAction;
-        private SmartspaceText mSupplementalAlarmText;
+        private Text mTitleText;
+        private Icon mTitleIcon;
+        private Text mSubtitleText;
+        private Icon mSubtitleIcon;
+        private TapAction mPrimaryTapAction;
+        private Text mSupplementalSubtitleText;
+        private Icon mSupplementalSubtitleIcon;
+        private TapAction mSupplementalSubtitleTapAction;
+        private Text mSupplementalAlarmText;
 
         /**
-         * A builder for {@link SmartspaceDefaultUiTemplateData}.
+         * A builder for {@link BaseTemplateData}.
          *
          * @param templateType the {@link UiTemplateType} of this template data.
          */
@@ -299,63 +316,63 @@
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        SmartspaceText getTitleText() {
+        Text getTitleText() {
             return mTitleText;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        SmartspaceIcon getTitleIcon() {
+        Icon getTitleIcon() {
             return mTitleIcon;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        SmartspaceText getSubtitleText() {
+        Text getSubtitleText() {
             return mSubtitleText;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        SmartspaceIcon getSubtitleIcon() {
+        Icon getSubtitleIcon() {
             return mSubtitleIcon;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        SmartspaceTapAction getPrimaryTapAction() {
+        TapAction getPrimaryTapAction() {
             return mPrimaryTapAction;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        SmartspaceText getSupplementalSubtitleText() {
+        Text getSupplementalSubtitleText() {
             return mSupplementalSubtitleText;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        SmartspaceIcon getSupplementalSubtitleIcon() {
+        Icon getSupplementalSubtitleIcon() {
             return mSupplementalSubtitleIcon;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        SmartspaceTapAction getSupplementalSubtitleTapAction() {
+        TapAction getSupplementalSubtitleTapAction() {
             return mSupplementalSubtitleTapAction;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        SmartspaceText getSupplementalAlarmText() {
+        Text getSupplementalAlarmText() {
             return mSupplementalAlarmText;
         }
 
@@ -363,7 +380,7 @@
          * Sets the card title.
          */
         @NonNull
-        public Builder setTitleText(@NonNull SmartspaceText titleText) {
+        public Builder setTitleText(@NonNull Text titleText) {
             mTitleText = titleText;
             return this;
         }
@@ -372,7 +389,7 @@
          * Sets the card title icon.
          */
         @NonNull
-        public Builder setTitleIcon(@NonNull SmartspaceIcon titleIcon) {
+        public Builder setTitleIcon(@NonNull Icon titleIcon) {
             mTitleIcon = titleIcon;
             return this;
         }
@@ -381,7 +398,7 @@
          * Sets the card subtitle.
          */
         @NonNull
-        public Builder setSubtitleText(@NonNull SmartspaceText subtitleText) {
+        public Builder setSubtitleText(@NonNull Text subtitleText) {
             mSubtitleText = subtitleText;
             return this;
         }
@@ -390,7 +407,7 @@
          * Sets the card subtitle icon.
          */
         @NonNull
-        public Builder setSubtitleIcon(@NonNull SmartspaceIcon subtitleIcon) {
+        public Builder setSubtitleIcon(@NonNull Icon subtitleIcon) {
             mSubtitleIcon = subtitleIcon;
             return this;
         }
@@ -399,7 +416,7 @@
          * Sets the card primary tap action.
          */
         @NonNull
-        public Builder setPrimaryTapAction(@NonNull SmartspaceTapAction primaryTapAction) {
+        public Builder setPrimaryTapAction(@NonNull TapAction primaryTapAction) {
             mPrimaryTapAction = primaryTapAction;
             return this;
         }
@@ -409,7 +426,7 @@
          */
         @NonNull
         public Builder setSupplementalSubtitleText(
-                @NonNull SmartspaceText supplementalSubtitleText) {
+                @NonNull Text supplementalSubtitleText) {
             mSupplementalSubtitleText = supplementalSubtitleText;
             return this;
         }
@@ -419,7 +436,7 @@
          */
         @NonNull
         public Builder setSupplementalSubtitleIcon(
-                @NonNull SmartspaceIcon supplementalSubtitleIcon) {
+                @NonNull Icon supplementalSubtitleIcon) {
             mSupplementalSubtitleIcon = supplementalSubtitleIcon;
             return this;
         }
@@ -431,7 +448,7 @@
          */
         @NonNull
         public Builder setSupplementalSubtitleTapAction(
-                @NonNull SmartspaceTapAction supplementalSubtitleTapAction) {
+                @NonNull TapAction supplementalSubtitleTapAction) {
             mSupplementalSubtitleTapAction = supplementalSubtitleTapAction;
             return this;
         }
@@ -440,7 +457,7 @@
          * Sets the supplemental alarm text.
          */
         @NonNull
-        public Builder setSupplementalAlarmText(@NonNull SmartspaceText supplementalAlarmText) {
+        public Builder setSupplementalAlarmText(@NonNull Text supplementalAlarmText) {
             mSupplementalAlarmText = supplementalAlarmText;
             return this;
         }
@@ -449,8 +466,8 @@
          * Builds a new SmartspaceDefaultUiTemplateData instance.
          */
         @NonNull
-        public SmartspaceDefaultUiTemplateData build() {
-            return new SmartspaceDefaultUiTemplateData(mTemplateType, mTitleText, mTitleIcon,
+        public BaseTemplateData build() {
+            return new BaseTemplateData(mTemplateType, mTitleText, mTitleIcon,
                     mSubtitleText, mSubtitleIcon, mPrimaryTapAction, mSupplementalSubtitleText,
                     mSupplementalSubtitleIcon, mSupplementalSubtitleTapAction,
                     mSupplementalAlarmText);
diff --git a/core/java/android/app/smartspace/uitemplatedata/SmartspaceCarouselUiTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/CarouselTemplateData.java
similarity index 69%
rename from core/java/android/app/smartspace/uitemplatedata/SmartspaceCarouselUiTemplateData.java
rename to core/java/android/app/smartspace/uitemplatedata/CarouselTemplateData.java
index e996056..feb1c34 100644
--- a/core/java/android/app/smartspace/uitemplatedata/SmartspaceCarouselUiTemplateData.java
+++ b/core/java/android/app/smartspace/uitemplatedata/CarouselTemplateData.java
@@ -30,10 +30,16 @@
 /**
  * Holds all the relevant data needed to render a Smartspace card with the carousel Ui Template.
  *
+ * This template will add a sub-card displaying a list of carousel items within the default-template
+ * card:
+ * <ul>
+ *     <li> carouselItem1, carouselItem2, carouselItem3... </li>
+ * </ul>
+ *
  * @hide
  */
 @SystemApi
-public final class SmartspaceCarouselUiTemplateData extends SmartspaceDefaultUiTemplateData {
+public final class CarouselTemplateData extends BaseTemplateData {
 
     /** Lists of {@link CarouselItem}. */
     @NonNull
@@ -41,26 +47,26 @@
 
     /** Tap action for the entire carousel secondary card, including the blank space */
     @Nullable
-    private final SmartspaceTapAction mCarouselAction;
+    private final TapAction mCarouselAction;
 
-    SmartspaceCarouselUiTemplateData(@NonNull Parcel in) {
+    CarouselTemplateData(@NonNull Parcel in) {
         super(in);
         mCarouselItems = in.createTypedArrayList(CarouselItem.CREATOR);
-        mCarouselAction = in.readTypedObject(SmartspaceTapAction.CREATOR);
+        mCarouselAction = in.readTypedObject(TapAction.CREATOR);
     }
 
-    private SmartspaceCarouselUiTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
-            @Nullable SmartspaceText titleText,
-            @Nullable SmartspaceIcon titleIcon,
-            @Nullable SmartspaceText subtitleText,
-            @Nullable SmartspaceIcon subTitleIcon,
-            @Nullable SmartspaceTapAction primaryTapAction,
-            @Nullable SmartspaceText supplementalSubtitleText,
-            @Nullable SmartspaceIcon supplementalSubtitleIcon,
-            @Nullable SmartspaceTapAction supplementalSubtitleTapAction,
-            @Nullable SmartspaceText supplementalAlarmText,
+    private CarouselTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
+            @Nullable Text titleText,
+            @Nullable Icon titleIcon,
+            @Nullable Text subtitleText,
+            @Nullable Icon subTitleIcon,
+            @Nullable TapAction primaryTapAction,
+            @Nullable Text supplementalSubtitleText,
+            @Nullable Icon supplementalSubtitleIcon,
+            @Nullable TapAction supplementalSubtitleTapAction,
+            @Nullable Text supplementalAlarmText,
             @NonNull List<CarouselItem> carouselItems,
-            @Nullable SmartspaceTapAction carouselAction) {
+            @Nullable TapAction carouselAction) {
         super(templateType, titleText, titleIcon, subtitleText, subTitleIcon, primaryTapAction,
                 supplementalSubtitleText, supplementalSubtitleIcon, supplementalSubtitleTapAction,
                 supplementalAlarmText);
@@ -68,13 +74,15 @@
         mCarouselAction = carouselAction;
     }
 
+    /** Returns the list of {@link CarouselItem}. Can be empty if not being set. */
     @NonNull
     public List<CarouselItem> getCarouselItems() {
         return mCarouselItems;
     }
 
+    /** Returns the card's tap action. */
     @Nullable
-    public SmartspaceTapAction getCarouselAction() {
+    public TapAction getCarouselAction() {
         return mCarouselAction;
     }
 
@@ -82,16 +90,16 @@
      * @see Parcelable.Creator
      */
     @NonNull
-    public static final Creator<SmartspaceCarouselUiTemplateData> CREATOR =
-            new Creator<SmartspaceCarouselUiTemplateData>() {
+    public static final Creator<CarouselTemplateData> CREATOR =
+            new Creator<CarouselTemplateData>() {
                 @Override
-                public SmartspaceCarouselUiTemplateData createFromParcel(Parcel in) {
-                    return new SmartspaceCarouselUiTemplateData(in);
+                public CarouselTemplateData createFromParcel(Parcel in) {
+                    return new CarouselTemplateData(in);
                 }
 
                 @Override
-                public SmartspaceCarouselUiTemplateData[] newArray(int size) {
-                    return new SmartspaceCarouselUiTemplateData[size];
+                public CarouselTemplateData[] newArray(int size) {
+                    return new CarouselTemplateData[size];
                 }
             };
 
@@ -111,9 +119,9 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (!(o instanceof SmartspaceCarouselUiTemplateData)) return false;
+        if (!(o instanceof CarouselTemplateData)) return false;
         if (!super.equals(o)) return false;
-        SmartspaceCarouselUiTemplateData that = (SmartspaceCarouselUiTemplateData) o;
+        CarouselTemplateData that = (CarouselTemplateData) o;
         return mCarouselItems.equals(that.mCarouselItems) && Objects.equals(mCarouselAction,
                 that.mCarouselAction);
     }
@@ -132,18 +140,18 @@
     }
 
     /**
-     * A builder for {@link SmartspaceCarouselUiTemplateData} object.
+     * A builder for {@link CarouselTemplateData} object.
      *
      * @hide
      */
     @SystemApi
-    public static final class Builder extends SmartspaceDefaultUiTemplateData.Builder {
+    public static final class Builder extends BaseTemplateData.Builder {
 
         private final List<CarouselItem> mCarouselItems;
-        private SmartspaceTapAction mCarouselAction;
+        private TapAction mCarouselAction;
 
         /**
-         * A builder for {@link SmartspaceCarouselUiTemplateData}.
+         * A builder for {@link CarouselTemplateData}.
          */
         public Builder(@NonNull List<CarouselItem> carouselItems) {
             super(SmartspaceTarget.UI_TEMPLATE_CAROUSEL);
@@ -154,23 +162,23 @@
          * Sets the card tap action.
          */
         @NonNull
-        public Builder setCarouselAction(@NonNull SmartspaceTapAction carouselAction) {
+        public Builder setCarouselAction(@NonNull TapAction carouselAction) {
             mCarouselAction = carouselAction;
             return this;
         }
 
         /**
-         * Builds a new SmartspaceCarouselUiTemplateData instance.
+         * Builds a new {@link CarouselTemplateData} instance.
          *
          * @throws IllegalStateException if the carousel data is invalid.
          */
         @NonNull
-        public SmartspaceCarouselUiTemplateData build() {
+        public CarouselTemplateData build() {
             if (mCarouselItems.isEmpty()) {
                 throw new IllegalStateException("Carousel data is empty");
             }
 
-            return new SmartspaceCarouselUiTemplateData(getTemplateType(), getTitleText(),
+            return new CarouselTemplateData(getTemplateType(), getTitleText(),
                     getTitleIcon(), getSubtitleText(), getSubtitleIcon(), getPrimaryTapAction(),
                     getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
                     getSupplementalSubtitleTapAction(), getSupplementalAlarmText(), mCarouselItems,
@@ -178,37 +186,45 @@
         }
     }
 
-    /** Holds all the relevant data needed to render a carousel item. */
+    /**
+     * Holds all the relevant data needed to render a carousel item.
+     *
+     * <ul>
+     *     <li> upper text </li>
+     *     <li> image </li>
+     *     <li> lower text </li>
+     * </ul>
+     */
     public static final class CarouselItem implements Parcelable {
 
         /** Text which is above the image item. */
         @Nullable
-        private final SmartspaceText mUpperText;
+        private final Text mUpperText;
 
         /** Image item. Can be empty. */
         @Nullable
-        private final SmartspaceIcon mImage;
+        private final Icon mImage;
 
         /** Text which is under the image item. */
         @Nullable
-        private final SmartspaceText mLowerText;
+        private final Text mLowerText;
 
         /**
          * Tap action for this {@link CarouselItem} instance. {@code mCarouselAction} is used if not
          * being set.
          */
         @Nullable
-        private final SmartspaceTapAction mTapAction;
+        private final TapAction mTapAction;
 
         CarouselItem(@NonNull Parcel in) {
-            mUpperText = in.readTypedObject(SmartspaceText.CREATOR);
-            mImage = in.readTypedObject(SmartspaceIcon.CREATOR);
-            mLowerText = in.readTypedObject(SmartspaceText.CREATOR);
-            mTapAction = in.readTypedObject(SmartspaceTapAction.CREATOR);
+            mUpperText = in.readTypedObject(Text.CREATOR);
+            mImage = in.readTypedObject(Icon.CREATOR);
+            mLowerText = in.readTypedObject(Text.CREATOR);
+            mTapAction = in.readTypedObject(TapAction.CREATOR);
         }
 
-        private CarouselItem(@Nullable SmartspaceText upperText, @Nullable SmartspaceIcon image,
-                @Nullable SmartspaceText lowerText, @Nullable SmartspaceTapAction tapAction) {
+        private CarouselItem(@Nullable Text upperText, @Nullable Icon image,
+                @Nullable Text lowerText, @Nullable TapAction tapAction) {
             mUpperText = upperText;
             mImage = image;
             mLowerText = lowerText;
@@ -216,22 +232,22 @@
         }
 
         @Nullable
-        public SmartspaceText getUpperText() {
+        public Text getUpperText() {
             return mUpperText;
         }
 
         @Nullable
-        public SmartspaceIcon getImage() {
+        public Icon getImage() {
             return mImage;
         }
 
         @Nullable
-        public SmartspaceText getLowerText() {
+        public Text getLowerText() {
             return mLowerText;
         }
 
         @Nullable
-        public SmartspaceTapAction getTapAction() {
+        public TapAction getTapAction() {
             return mTapAction;
         }
 
@@ -299,16 +315,16 @@
         @SystemApi
         public static final class Builder {
 
-            private SmartspaceText mUpperText;
-            private SmartspaceIcon mImage;
-            private SmartspaceText mLowerText;
-            private SmartspaceTapAction mTapAction;
+            private Text mUpperText;
+            private Icon mImage;
+            private Text mLowerText;
+            private TapAction mTapAction;
 
             /**
              * Sets the upper text.
              */
             @NonNull
-            public Builder setUpperText(@Nullable SmartspaceText upperText) {
+            public Builder setUpperText(@Nullable Text upperText) {
                 mUpperText = upperText;
                 return this;
             }
@@ -317,7 +333,7 @@
              * Sets the image.
              */
             @NonNull
-            public Builder setImage(@Nullable SmartspaceIcon image) {
+            public Builder setImage(@Nullable Icon image) {
                 mImage = image;
                 return this;
             }
@@ -327,7 +343,7 @@
              * Sets the lower text.
              */
             @NonNull
-            public Builder setLowerText(@Nullable SmartspaceText lowerText) {
+            public Builder setLowerText(@Nullable Text lowerText) {
                 mLowerText = lowerText;
                 return this;
             }
@@ -336,7 +352,7 @@
              * Sets the tap action.
              */
             @NonNull
-            public Builder setTapAction(@Nullable SmartspaceTapAction tapAction) {
+            public Builder setTapAction(@Nullable TapAction tapAction) {
                 mTapAction = tapAction;
                 return this;
             }
diff --git a/core/java/android/app/smartspace/uitemplatedata/CombinedCardsTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/CombinedCardsTemplateData.java
new file mode 100644
index 0000000..13091e2
--- /dev/null
+++ b/core/java/android/app/smartspace/uitemplatedata/CombinedCardsTemplateData.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace.uitemplatedata;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.smartspace.SmartspaceTarget;
+import android.os.Parcel;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Holds all the relevant data needed to render a Smartspace card with the combined-card Ui
+ * Template.
+ *
+ * We only support adding a 1 sub-list card combined with 1 sub-card card (may expand our supported
+ * combinations in the future) within the default-template card:
+ *
+ * <ul>
+ *     <li> sub-list card, sub-card card </li>
+ * </ul>
+ *
+ * @hide
+ */
+@SystemApi
+public final class CombinedCardsTemplateData extends BaseTemplateData {
+
+    /** A list of secondary cards. */
+    @NonNull
+    private final List<BaseTemplateData> mCombinedCardDataList;
+
+    CombinedCardsTemplateData(@NonNull Parcel in) {
+        super(in);
+        mCombinedCardDataList = in.createTypedArrayList(BaseTemplateData.CREATOR);
+    }
+
+    private CombinedCardsTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
+            @Nullable Text titleText,
+            @Nullable Icon titleIcon,
+            @Nullable Text subtitleText,
+            @Nullable Icon subTitleIcon,
+            @Nullable TapAction primaryTapAction,
+            @Nullable Text supplementalSubtitleText,
+            @Nullable Icon supplementalSubtitleIcon,
+            @Nullable TapAction supplementalSubtitleTapAction,
+            @Nullable Text supplementalAlarmText,
+            @NonNull List<BaseTemplateData> combinedCardDataList) {
+        super(templateType, titleText, titleIcon, subtitleText, subTitleIcon, primaryTapAction,
+                supplementalSubtitleText, supplementalSubtitleIcon, supplementalSubtitleTapAction,
+                supplementalAlarmText);
+        mCombinedCardDataList = combinedCardDataList;
+    }
+
+    /** Returns the list of secondary cards. Can be null if not being set. */
+    @NonNull
+    public List<BaseTemplateData> getCombinedCardDataList() {
+        return mCombinedCardDataList;
+    }
+
+    /**
+     * @see Parcelable.Creator
+     */
+    @NonNull
+    public static final Creator<CombinedCardsTemplateData> CREATOR =
+            new Creator<CombinedCardsTemplateData>() {
+                @Override
+                public CombinedCardsTemplateData createFromParcel(Parcel in) {
+                    return new CombinedCardsTemplateData(in);
+                }
+
+                @Override
+                public CombinedCardsTemplateData[] newArray(int size) {
+                    return new CombinedCardsTemplateData[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        super.writeToParcel(out, flags);
+        out.writeTypedList(mCombinedCardDataList);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof CombinedCardsTemplateData)) return false;
+        if (!super.equals(o)) return false;
+        CombinedCardsTemplateData that = (CombinedCardsTemplateData) o;
+        return mCombinedCardDataList.equals(that.mCombinedCardDataList);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), mCombinedCardDataList);
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + " + SmartspaceCombinedCardsUiTemplateData{"
+                + "mCombinedCardDataList=" + mCombinedCardDataList
+                + '}';
+    }
+
+    /**
+     * A builder for {@link CombinedCardsTemplateData} object.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class Builder extends BaseTemplateData.Builder {
+
+        private final List<BaseTemplateData> mCombinedCardDataList;
+
+        /**
+         * A builder for {@link CombinedCardsTemplateData}.
+         */
+        public Builder(@NonNull List<BaseTemplateData> combinedCardDataList) {
+            super(SmartspaceTarget.UI_TEMPLATE_COMBINED_CARDS);
+            mCombinedCardDataList = Objects.requireNonNull(combinedCardDataList);
+        }
+
+        /**
+         * Builds a new SmartspaceCombinedCardsUiTemplateData instance.
+         *
+         * @throws IllegalStateException if any required non-null field is null
+         */
+        @NonNull
+        public CombinedCardsTemplateData build() {
+            if (mCombinedCardDataList == null) {
+                throw new IllegalStateException("Please assign a value to all @NonNull args.");
+            }
+            return new CombinedCardsTemplateData(getTemplateType(), getTitleText(),
+                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(), getPrimaryTapAction(),
+                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
+                    getSupplementalSubtitleTapAction(), getSupplementalAlarmText(),
+                    mCombinedCardDataList);
+        }
+    }
+}
diff --git a/core/java/android/app/smartspace/uitemplatedata/SmartspaceHeadToHeadUiTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/HeadToHeadTemplateData.java
similarity index 62%
rename from core/java/android/app/smartspace/uitemplatedata/SmartspaceHeadToHeadUiTemplateData.java
rename to core/java/android/app/smartspace/uitemplatedata/HeadToHeadTemplateData.java
index bcd12eb..eb56e93 100644
--- a/core/java/android/app/smartspace/uitemplatedata/SmartspaceHeadToHeadUiTemplateData.java
+++ b/core/java/android/app/smartspace/uitemplatedata/HeadToHeadTemplateData.java
@@ -28,52 +28,59 @@
 /**
  * Holds all the relevant data needed to render a Smartspace card with the head-to-head Ui Template.
  *
+ * This template will add a head-to-head card within the default-template card:
+ * <ul>
+ *                     <li> head-to-head title </li>
+ *     <li> first-competitor icon       second-competitor icon </li>
+ *     <li> first-competitor text       second-competitor text </li>
+ * </ul>
+ *
  * @hide
  */
 @SystemApi
-public final class SmartspaceHeadToHeadUiTemplateData extends SmartspaceDefaultUiTemplateData {
+public final class HeadToHeadTemplateData extends BaseTemplateData {
 
     @Nullable
-    private final SmartspaceText mHeadToHeadTitle;
+    private final Text mHeadToHeadTitle;
     @Nullable
-    private final SmartspaceIcon mHeadToHeadFirstCompetitorIcon;
+    private final Icon mHeadToHeadFirstCompetitorIcon;
     @Nullable
-    private final SmartspaceIcon mHeadToHeadSecondCompetitorIcon;
+    private final Icon mHeadToHeadSecondCompetitorIcon;
     @Nullable
-    private final SmartspaceText mHeadToHeadFirstCompetitorText;
+    private final Text mHeadToHeadFirstCompetitorText;
     @Nullable
-    private final SmartspaceText mHeadToHeadSecondCompetitorText;
+    private final Text mHeadToHeadSecondCompetitorText;
 
     /** Tap action for the head-to-head secondary card. */
     @Nullable
-    private final SmartspaceTapAction mHeadToHeadAction;
+    private final TapAction mHeadToHeadAction;
 
-    SmartspaceHeadToHeadUiTemplateData(@NonNull Parcel in) {
+    HeadToHeadTemplateData(@NonNull Parcel in) {
         super(in);
-        mHeadToHeadTitle = in.readTypedObject(SmartspaceText.CREATOR);
-        mHeadToHeadFirstCompetitorIcon = in.readTypedObject(SmartspaceIcon.CREATOR);
-        mHeadToHeadSecondCompetitorIcon = in.readTypedObject(SmartspaceIcon.CREATOR);
-        mHeadToHeadFirstCompetitorText = in.readTypedObject(SmartspaceText.CREATOR);
-        mHeadToHeadSecondCompetitorText = in.readTypedObject(SmartspaceText.CREATOR);
-        mHeadToHeadAction = in.readTypedObject(SmartspaceTapAction.CREATOR);
+        mHeadToHeadTitle = in.readTypedObject(Text.CREATOR);
+        mHeadToHeadFirstCompetitorIcon = in.readTypedObject(Icon.CREATOR);
+        mHeadToHeadSecondCompetitorIcon = in.readTypedObject(Icon.CREATOR);
+        mHeadToHeadFirstCompetitorText = in.readTypedObject(Text.CREATOR);
+        mHeadToHeadSecondCompetitorText = in.readTypedObject(Text.CREATOR);
+        mHeadToHeadAction = in.readTypedObject(TapAction.CREATOR);
     }
 
-    private SmartspaceHeadToHeadUiTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
-            @Nullable SmartspaceText titleText,
-            @Nullable SmartspaceIcon titleIcon,
-            @Nullable SmartspaceText subtitleText,
-            @Nullable SmartspaceIcon subTitleIcon,
-            @Nullable SmartspaceTapAction primaryTapAction,
-            @Nullable SmartspaceText supplementalSubtitleText,
-            @Nullable SmartspaceIcon supplementalSubtitleIcon,
-            @Nullable SmartspaceTapAction supplementalSubtitleTapAction,
-            @Nullable SmartspaceText supplementalAlarmText,
-            @Nullable SmartspaceText headToHeadTitle,
-            @Nullable SmartspaceIcon headToHeadFirstCompetitorIcon,
-            @Nullable SmartspaceIcon headToHeadSecondCompetitorIcon,
-            @Nullable SmartspaceText headToHeadFirstCompetitorText,
-            @Nullable SmartspaceText headToHeadSecondCompetitorText,
-            @Nullable SmartspaceTapAction headToHeadAction) {
+    private HeadToHeadTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
+            @Nullable Text titleText,
+            @Nullable Icon titleIcon,
+            @Nullable Text subtitleText,
+            @Nullable Icon subTitleIcon,
+            @Nullable TapAction primaryTapAction,
+            @Nullable Text supplementalSubtitleText,
+            @Nullable Icon supplementalSubtitleIcon,
+            @Nullable TapAction supplementalSubtitleTapAction,
+            @Nullable Text supplementalAlarmText,
+            @Nullable Text headToHeadTitle,
+            @Nullable Icon headToHeadFirstCompetitorIcon,
+            @Nullable Icon headToHeadSecondCompetitorIcon,
+            @Nullable Text headToHeadFirstCompetitorText,
+            @Nullable Text headToHeadSecondCompetitorText,
+            @Nullable TapAction headToHeadAction) {
         super(templateType, titleText, titleIcon, subtitleText, subTitleIcon, primaryTapAction,
                 supplementalSubtitleText, supplementalSubtitleIcon, supplementalSubtitleTapAction,
                 supplementalAlarmText);
@@ -85,33 +92,39 @@
         mHeadToHeadAction = headToHeadAction;
     }
 
+    /** Returns the head-to-head card's title. */
     @Nullable
-    public SmartspaceText getHeadToHeadTitle() {
+    public Text getHeadToHeadTitle() {
         return mHeadToHeadTitle;
     }
 
+    /** Returns the first competitor's icon. */
     @Nullable
-    public SmartspaceIcon getHeadToHeadFirstCompetitorIcon() {
+    public Icon getHeadToHeadFirstCompetitorIcon() {
         return mHeadToHeadFirstCompetitorIcon;
     }
 
+    /** Returns the second competitor's icon. */
     @Nullable
-    public SmartspaceIcon getHeadToHeadSecondCompetitorIcon() {
+    public Icon getHeadToHeadSecondCompetitorIcon() {
         return mHeadToHeadSecondCompetitorIcon;
     }
 
+    /** Returns the first competitor's text. */
     @Nullable
-    public SmartspaceText getHeadToHeadFirstCompetitorText() {
+    public Text getHeadToHeadFirstCompetitorText() {
         return mHeadToHeadFirstCompetitorText;
     }
 
+    /** Returns the second competitor's text. */
     @Nullable
-    public SmartspaceText getHeadToHeadSecondCompetitorText() {
+    public Text getHeadToHeadSecondCompetitorText() {
         return mHeadToHeadSecondCompetitorText;
     }
 
+    /** Returns the head-to-head card's tap action. */
     @Nullable
-    public SmartspaceTapAction getHeadToHeadAction() {
+    public TapAction getHeadToHeadAction() {
         return mHeadToHeadAction;
     }
 
@@ -119,16 +132,16 @@
      * @see Parcelable.Creator
      */
     @NonNull
-    public static final Creator<SmartspaceHeadToHeadUiTemplateData> CREATOR =
-            new Creator<SmartspaceHeadToHeadUiTemplateData>() {
+    public static final Creator<HeadToHeadTemplateData> CREATOR =
+            new Creator<HeadToHeadTemplateData>() {
                 @Override
-                public SmartspaceHeadToHeadUiTemplateData createFromParcel(Parcel in) {
-                    return new SmartspaceHeadToHeadUiTemplateData(in);
+                public HeadToHeadTemplateData createFromParcel(Parcel in) {
+                    return new HeadToHeadTemplateData(in);
                 }
 
                 @Override
-                public SmartspaceHeadToHeadUiTemplateData[] newArray(int size) {
-                    return new SmartspaceHeadToHeadUiTemplateData[size];
+                public HeadToHeadTemplateData[] newArray(int size) {
+                    return new HeadToHeadTemplateData[size];
                 }
             };
 
@@ -151,9 +164,9 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (!(o instanceof SmartspaceHeadToHeadUiTemplateData)) return false;
+        if (!(o instanceof HeadToHeadTemplateData)) return false;
         if (!super.equals(o)) return false;
-        SmartspaceHeadToHeadUiTemplateData that = (SmartspaceHeadToHeadUiTemplateData) o;
+        HeadToHeadTemplateData that = (HeadToHeadTemplateData) o;
         return SmartspaceUtils.isEqual(mHeadToHeadTitle, that.mHeadToHeadTitle) && Objects.equals(
                 mHeadToHeadFirstCompetitorIcon, that.mHeadToHeadFirstCompetitorIcon)
                 && Objects.equals(
@@ -187,22 +200,22 @@
     }
 
     /**
-     * A builder for {@link SmartspaceHeadToHeadUiTemplateData} object.
+     * A builder for {@link HeadToHeadTemplateData} object.
      *
      * @hide
      */
     @SystemApi
-    public static final class Builder extends SmartspaceDefaultUiTemplateData.Builder {
+    public static final class Builder extends BaseTemplateData.Builder {
 
-        private SmartspaceText mHeadToHeadTitle;
-        private SmartspaceIcon mHeadToHeadFirstCompetitorIcon;
-        private SmartspaceIcon mHeadToHeadSecondCompetitorIcon;
-        private SmartspaceText mHeadToHeadFirstCompetitorText;
-        private SmartspaceText mHeadToHeadSecondCompetitorText;
-        private SmartspaceTapAction mHeadToHeadAction;
+        private Text mHeadToHeadTitle;
+        private Icon mHeadToHeadFirstCompetitorIcon;
+        private Icon mHeadToHeadSecondCompetitorIcon;
+        private Text mHeadToHeadFirstCompetitorText;
+        private Text mHeadToHeadSecondCompetitorText;
+        private TapAction mHeadToHeadAction;
 
         /**
-         * A builder for {@link SmartspaceHeadToHeadUiTemplateData}.
+         * A builder for {@link HeadToHeadTemplateData}.
          */
         public Builder() {
             super(SmartspaceTarget.UI_TEMPLATE_HEAD_TO_HEAD);
@@ -212,7 +225,7 @@
          * Sets the head-to-head card's title
          */
         @NonNull
-        public Builder setHeadToHeadTitle(@Nullable SmartspaceText headToHeadTitle) {
+        public Builder setHeadToHeadTitle(@Nullable Text headToHeadTitle) {
             mHeadToHeadTitle = headToHeadTitle;
             return this;
         }
@@ -222,7 +235,7 @@
          */
         @NonNull
         public Builder setHeadToHeadFirstCompetitorIcon(
-                @Nullable SmartspaceIcon headToHeadFirstCompetitorIcon) {
+                @Nullable Icon headToHeadFirstCompetitorIcon) {
             mHeadToHeadFirstCompetitorIcon = headToHeadFirstCompetitorIcon;
             return this;
         }
@@ -232,7 +245,7 @@
          */
         @NonNull
         public Builder setHeadToHeadSecondCompetitorIcon(
-                @Nullable SmartspaceIcon headToHeadSecondCompetitorIcon) {
+                @Nullable Icon headToHeadSecondCompetitorIcon) {
             mHeadToHeadSecondCompetitorIcon = headToHeadSecondCompetitorIcon;
             return this;
         }
@@ -242,7 +255,7 @@
          */
         @NonNull
         public Builder setHeadToHeadFirstCompetitorText(
-                @Nullable SmartspaceText headToHeadFirstCompetitorText) {
+                @Nullable Text headToHeadFirstCompetitorText) {
             mHeadToHeadFirstCompetitorText = headToHeadFirstCompetitorText;
             return this;
         }
@@ -252,7 +265,7 @@
          */
         @NonNull
         public Builder setHeadToHeadSecondCompetitorText(
-                @Nullable SmartspaceText headToHeadSecondCompetitorText) {
+                @Nullable Text headToHeadSecondCompetitorText) {
             mHeadToHeadSecondCompetitorText = headToHeadSecondCompetitorText;
             return this;
         }
@@ -261,7 +274,7 @@
          * Sets the head-to-head card's tap action
          */
         @NonNull
-        public Builder setHeadToHeadAction(@Nullable SmartspaceTapAction headToHeadAction) {
+        public Builder setHeadToHeadAction(@Nullable TapAction headToHeadAction) {
             mHeadToHeadAction = headToHeadAction;
             return this;
         }
@@ -270,8 +283,8 @@
          * Builds a new SmartspaceHeadToHeadUiTemplateData instance.
          */
         @NonNull
-        public SmartspaceHeadToHeadUiTemplateData build() {
-            return new SmartspaceHeadToHeadUiTemplateData(getTemplateType(), getTitleText(),
+        public HeadToHeadTemplateData build() {
+            return new HeadToHeadTemplateData(getTemplateType(), getTitleText(),
                     getTitleIcon(), getSubtitleText(), getSubtitleIcon(), getPrimaryTapAction(),
                     getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
                     getSupplementalSubtitleTapAction(), getSupplementalAlarmText(),
diff --git a/core/java/android/app/smartspace/uitemplatedata/SmartspaceIcon.java b/core/java/android/app/smartspace/uitemplatedata/Icon.java
similarity index 75%
rename from core/java/android/app/smartspace/uitemplatedata/SmartspaceIcon.java
rename to core/java/android/app/smartspace/uitemplatedata/Icon.java
index 1efbaeb..2b1f420 100644
--- a/core/java/android/app/smartspace/uitemplatedata/SmartspaceIcon.java
+++ b/core/java/android/app/smartspace/uitemplatedata/Icon.java
@@ -20,7 +20,6 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.app.smartspace.SmartspaceUtils;
-import android.graphics.drawable.Icon;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -34,34 +33,37 @@
  * @hide
  */
 @SystemApi
-public final class SmartspaceIcon implements Parcelable {
+public final class Icon implements Parcelable {
 
     @NonNull
-    private final Icon mIcon;
+    private final android.graphics.drawable.Icon mIcon;
 
     @Nullable
     private final CharSequence mContentDescription;
 
     private final boolean mShouldTint;
 
-    SmartspaceIcon(@NonNull Parcel in) {
-        mIcon = in.readTypedObject(Icon.CREATOR);
+    Icon(@NonNull Parcel in) {
+        mIcon = in.readTypedObject(android.graphics.drawable.Icon.CREATOR);
         mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mShouldTint = in.readBoolean();
     }
 
-    private SmartspaceIcon(@NonNull Icon icon, @Nullable CharSequence contentDescription,
+    private Icon(@NonNull android.graphics.drawable.Icon icon,
+            @Nullable CharSequence contentDescription,
             boolean shouldTint) {
         mIcon = icon;
         mContentDescription = contentDescription;
         mShouldTint = shouldTint;
     }
 
+    /** Returns the icon image. */
     @NonNull
-    public Icon getIcon() {
+    public android.graphics.drawable.Icon getIcon() {
         return mIcon;
     }
 
+    /** Returns the content description of the icon image. */
     @Nullable
     public CharSequence getContentDescription() {
         return mContentDescription;
@@ -73,23 +75,23 @@
     }
 
     @NonNull
-    public static final Creator<SmartspaceIcon> CREATOR = new Creator<SmartspaceIcon>() {
+    public static final Creator<Icon> CREATOR = new Creator<Icon>() {
         @Override
-        public SmartspaceIcon createFromParcel(Parcel in) {
-            return new SmartspaceIcon(in);
+        public Icon createFromParcel(Parcel in) {
+            return new Icon(in);
         }
 
         @Override
-        public SmartspaceIcon[] newArray(int size) {
-            return new SmartspaceIcon[size];
+        public Icon[] newArray(int size) {
+            return new Icon[size];
         }
     };
 
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (!(o instanceof SmartspaceIcon)) return false;
-        SmartspaceIcon that = (SmartspaceIcon) o;
+        if (!(o instanceof Icon)) return false;
+        Icon that = (Icon) o;
         return mIcon.toString().equals(that.mIcon.toString()) && SmartspaceUtils.isEqual(
                 mContentDescription,
                 that.mContentDescription) && mShouldTint == that.mShouldTint;
@@ -122,23 +124,23 @@
     }
 
     /**
-     * A builder for {@link SmartspaceIcon} object.
+     * A builder for {@link Icon} object.
      *
      * @hide
      */
     @SystemApi
     public static final class Builder {
 
-        private Icon mIcon;
+        private android.graphics.drawable.Icon mIcon;
         private CharSequence mContentDescription;
         private boolean mShouldTint;
 
         /**
-         * A builder for {@link SmartspaceIcon}, which sets shouldTint to true by default.
+         * A builder for {@link Icon}, which sets shouldTint to true by default.
          *
-         * @param icon the icon image of this {@link SmartspaceIcon} instance.
+         * @param icon the icon image of this {@link Icon} instance.
          */
-        public Builder(@NonNull Icon icon) {
+        public Builder(@NonNull android.graphics.drawable.Icon icon) {
             mIcon = Objects.requireNonNull(icon);
             mShouldTint = true;
         }
@@ -165,8 +167,8 @@
          * Builds a new SmartspaceIcon instance.
          */
         @NonNull
-        public SmartspaceIcon build() {
-            return new SmartspaceIcon(mIcon, mContentDescription, mShouldTint);
+        public Icon build() {
+            return new Icon(mIcon, mContentDescription, mShouldTint);
         }
     }
 }
diff --git a/core/java/android/app/smartspace/uitemplatedata/SmartspaceCombinedCardsUiTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/SmartspaceCombinedCardsUiTemplateData.java
deleted file mode 100644
index 9d4c8e2..0000000
--- a/core/java/android/app/smartspace/uitemplatedata/SmartspaceCombinedCardsUiTemplateData.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.smartspace.uitemplatedata;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.app.smartspace.SmartspaceTarget;
-import android.os.Parcel;
-
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Holds all the relevant data needed to render a Smartspace card with the combined-card Ui
- * Template.
- *
- * We only support 1 sub-list card combined with 1 carousel card. And we may expand our supported
- * combinations in the future.
- *
- * @hide
- */
-@SystemApi
-public final class SmartspaceCombinedCardsUiTemplateData extends SmartspaceDefaultUiTemplateData {
-
-    /** A list of secondary cards. */
-    @NonNull
-    private final List<SmartspaceDefaultUiTemplateData> mCombinedCardDataList;
-
-    SmartspaceCombinedCardsUiTemplateData(@NonNull Parcel in) {
-        super(in);
-        mCombinedCardDataList = in.createTypedArrayList(SmartspaceDefaultUiTemplateData.CREATOR);
-    }
-
-    private SmartspaceCombinedCardsUiTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
-            @Nullable SmartspaceText titleText,
-            @Nullable SmartspaceIcon titleIcon,
-            @Nullable SmartspaceText subtitleText,
-            @Nullable SmartspaceIcon subTitleIcon,
-            @Nullable SmartspaceTapAction primaryTapAction,
-            @Nullable SmartspaceText supplementalSubtitleText,
-            @Nullable SmartspaceIcon supplementalSubtitleIcon,
-            @Nullable SmartspaceTapAction supplementalSubtitleTapAction,
-            @Nullable SmartspaceText supplementalAlarmText,
-            @NonNull List<SmartspaceDefaultUiTemplateData> combinedCardDataList) {
-        super(templateType, titleText, titleIcon, subtitleText, subTitleIcon, primaryTapAction,
-                supplementalSubtitleText, supplementalSubtitleIcon, supplementalSubtitleTapAction,
-                supplementalAlarmText);
-        mCombinedCardDataList = combinedCardDataList;
-    }
-
-    @NonNull
-    public List<SmartspaceDefaultUiTemplateData> getCombinedCardDataList() {
-        return mCombinedCardDataList;
-    }
-
-    /**
-     * @see Parcelable.Creator
-     */
-    @NonNull
-    public static final Creator<SmartspaceCombinedCardsUiTemplateData> CREATOR =
-            new Creator<SmartspaceCombinedCardsUiTemplateData>() {
-                @Override
-                public SmartspaceCombinedCardsUiTemplateData createFromParcel(Parcel in) {
-                    return new SmartspaceCombinedCardsUiTemplateData(in);
-                }
-
-                @Override
-                public SmartspaceCombinedCardsUiTemplateData[] newArray(int size) {
-                    return new SmartspaceCombinedCardsUiTemplateData[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel out, int flags) {
-        super.writeToParcel(out, flags);
-        out.writeTypedList(mCombinedCardDataList);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof SmartspaceCombinedCardsUiTemplateData)) return false;
-        if (!super.equals(o)) return false;
-        SmartspaceCombinedCardsUiTemplateData that = (SmartspaceCombinedCardsUiTemplateData) o;
-        return mCombinedCardDataList.equals(that.mCombinedCardDataList);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(super.hashCode(), mCombinedCardDataList);
-    }
-
-    @Override
-    public String toString() {
-        return super.toString() + " + SmartspaceCombinedCardsUiTemplateData{"
-                + "mCombinedCardDataList=" + mCombinedCardDataList
-                + '}';
-    }
-
-    /**
-     * A builder for {@link SmartspaceCombinedCardsUiTemplateData} object.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final class Builder extends SmartspaceDefaultUiTemplateData.Builder {
-
-        private final List<SmartspaceDefaultUiTemplateData> mCombinedCardDataList;
-
-        /**
-         * A builder for {@link SmartspaceCombinedCardsUiTemplateData}.
-         */
-        public Builder(@NonNull List<SmartspaceDefaultUiTemplateData> combinedCardDataList) {
-            super(SmartspaceTarget.UI_TEMPLATE_COMBINED_CARDS);
-            mCombinedCardDataList = Objects.requireNonNull(combinedCardDataList);
-        }
-
-        /**
-         * Builds a new SmartspaceCombinedCardsUiTemplateData instance.
-         *
-         * @throws IllegalStateException if any required non-null field is null
-         */
-        @NonNull
-        public SmartspaceCombinedCardsUiTemplateData build() {
-            if (mCombinedCardDataList == null) {
-                throw new IllegalStateException("Please assign a value to all @NonNull args.");
-            }
-            return new SmartspaceCombinedCardsUiTemplateData(getTemplateType(), getTitleText(),
-                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(), getPrimaryTapAction(),
-                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
-                    getSupplementalSubtitleTapAction(), getSupplementalAlarmText(),
-                    mCombinedCardDataList);
-        }
-    }
-}
diff --git a/core/java/android/app/smartspace/uitemplatedata/SmartspaceSubImageUiTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/SmartspaceSubImageUiTemplateData.java
deleted file mode 100644
index 2fe4cf8..0000000
--- a/core/java/android/app/smartspace/uitemplatedata/SmartspaceSubImageUiTemplateData.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.smartspace.uitemplatedata;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.app.smartspace.SmartspaceTarget;
-import android.os.Parcel;
-
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Holds all the relevant data needed to render a Smartspace card with the sub-image Ui Template.
- *
- * @hide
- */
-@SystemApi
-public final class SmartspaceSubImageUiTemplateData extends SmartspaceDefaultUiTemplateData {
-
-    /** Texts are shown next to the image as a vertical list */
-    @NonNull
-    private final List<SmartspaceText> mSubImageTexts;
-
-    /** If multiple images are passed in, they will be rendered as GIF. */
-    @NonNull
-    private final List<SmartspaceIcon> mSubImages;
-
-    /** Tap action for the sub-image secondary card. */
-    @Nullable
-    private final SmartspaceTapAction mSubImageAction;
-
-    SmartspaceSubImageUiTemplateData(@NonNull Parcel in) {
-        super(in);
-        mSubImageTexts = in.createTypedArrayList(SmartspaceText.CREATOR);
-        mSubImages = in.createTypedArrayList(SmartspaceIcon.CREATOR);
-        mSubImageAction = in.readTypedObject(SmartspaceTapAction.CREATOR);
-    }
-
-    private SmartspaceSubImageUiTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
-            @Nullable SmartspaceText titleText,
-            @Nullable SmartspaceIcon titleIcon,
-            @Nullable SmartspaceText subtitleText,
-            @Nullable SmartspaceIcon subTitleIcon,
-            @Nullable SmartspaceTapAction primaryTapAction,
-            @Nullable SmartspaceText supplementalSubtitleText,
-            @Nullable SmartspaceIcon supplementalSubtitleIcon,
-            @Nullable SmartspaceTapAction supplementalSubtitleTapAction,
-            @Nullable SmartspaceText supplementalAlarmText,
-            @NonNull List<SmartspaceText> subImageTexts,
-            @NonNull List<SmartspaceIcon> subImages,
-            @Nullable SmartspaceTapAction subImageAction) {
-        super(templateType, titleText, titleIcon, subtitleText, subTitleIcon, primaryTapAction,
-                supplementalSubtitleText, supplementalSubtitleIcon, supplementalSubtitleTapAction,
-                supplementalAlarmText);
-        mSubImageTexts = subImageTexts;
-        mSubImages = subImages;
-        mSubImageAction = subImageAction;
-    }
-
-    @NonNull
-    public List<SmartspaceText> getSubImageTexts() {
-        return mSubImageTexts;
-    }
-
-    @NonNull
-    public List<SmartspaceIcon> getSubImages() {
-        return mSubImages;
-    }
-
-    @Nullable
-    public SmartspaceTapAction getSubImageAction() {
-        return mSubImageAction;
-    }
-
-    /**
-     * @see Parcelable.Creator
-     */
-    @NonNull
-    public static final Creator<SmartspaceSubImageUiTemplateData> CREATOR =
-            new Creator<SmartspaceSubImageUiTemplateData>() {
-                @Override
-                public SmartspaceSubImageUiTemplateData createFromParcel(Parcel in) {
-                    return new SmartspaceSubImageUiTemplateData(in);
-                }
-
-                @Override
-                public SmartspaceSubImageUiTemplateData[] newArray(int size) {
-                    return new SmartspaceSubImageUiTemplateData[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel out, int flags) {
-        super.writeToParcel(out, flags);
-        out.writeTypedList(mSubImageTexts);
-        out.writeTypedList(mSubImages);
-        out.writeTypedObject(mSubImageAction, flags);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof SmartspaceSubImageUiTemplateData)) return false;
-        if (!super.equals(o)) return false;
-        SmartspaceSubImageUiTemplateData that = (SmartspaceSubImageUiTemplateData) o;
-        return Objects.equals(mSubImageTexts, that.mSubImageTexts)
-                && Objects.equals(mSubImages, that.mSubImages) && Objects.equals(
-                mSubImageAction, that.mSubImageAction);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(super.hashCode(), mSubImageTexts, mSubImages, mSubImageAction);
-    }
-
-    @Override
-    public String toString() {
-        return super.toString() + " + SmartspaceSubImageUiTemplateData{"
-                + "mSubImageTexts=" + mSubImageTexts
-                + ", mSubImages=" + mSubImages
-                + ", mSubImageAction=" + mSubImageAction
-                + '}';
-    }
-
-    /**
-     * A builder for {@link SmartspaceSubImageUiTemplateData} object.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final class Builder extends SmartspaceDefaultUiTemplateData.Builder {
-
-        private final List<SmartspaceText> mSubImageTexts;
-        private final List<SmartspaceIcon> mSubImages;
-        private SmartspaceTapAction mSubImageAction;
-
-        /**
-         * A builder for {@link SmartspaceSubImageUiTemplateData}.
-         */
-        public Builder(@NonNull List<SmartspaceText> subImageTexts,
-                @NonNull List<SmartspaceIcon> subImages) {
-            super(SmartspaceTarget.UI_TEMPLATE_SUB_IMAGE);
-            mSubImageTexts = Objects.requireNonNull(subImageTexts);
-            mSubImages = Objects.requireNonNull(subImages);
-        }
-
-        /**
-         * Sets the card tap action.
-         */
-        @NonNull
-        public Builder setSubImageAction(@NonNull SmartspaceTapAction subImageAction) {
-            mSubImageAction = subImageAction;
-            return this;
-        }
-
-        /**
-         * Builds a new SmartspaceSubImageUiTemplateData instance.
-         */
-        @NonNull
-        public SmartspaceSubImageUiTemplateData build() {
-            return new SmartspaceSubImageUiTemplateData(getTemplateType(), getTitleText(),
-                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(), getPrimaryTapAction(),
-                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
-                    getSupplementalSubtitleTapAction(), getSupplementalAlarmText(), mSubImageTexts,
-                    mSubImages,
-                    mSubImageAction);
-        }
-    }
-}
diff --git a/core/java/android/app/smartspace/uitemplatedata/SmartspaceSubListUiTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/SmartspaceSubListUiTemplateData.java
deleted file mode 100644
index 9512c7f..0000000
--- a/core/java/android/app/smartspace/uitemplatedata/SmartspaceSubListUiTemplateData.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.smartspace.uitemplatedata;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.app.smartspace.SmartspaceTarget;
-import android.os.Parcel;
-
-import java.util.List;
-import java.util.Objects;
-
-
-/**
- * Holds all the relevant data needed to render a Smartspace card with the sub-list Ui Template.
- *
- * @hide
- */
-@SystemApi
-public final class SmartspaceSubListUiTemplateData extends SmartspaceDefaultUiTemplateData {
-
-    @Nullable
-    private final SmartspaceIcon mSubListIcon;
-    @NonNull
-    private final List<SmartspaceText> mSubListTexts;
-
-    /** Tap action for the sub-list secondary card. */
-    @Nullable
-    private final SmartspaceTapAction mSubListAction;
-
-    SmartspaceSubListUiTemplateData(@NonNull Parcel in) {
-        super(in);
-        mSubListIcon = in.readTypedObject(SmartspaceIcon.CREATOR);
-        mSubListTexts = in.createTypedArrayList(SmartspaceText.CREATOR);
-        mSubListAction = in.readTypedObject(SmartspaceTapAction.CREATOR);
-    }
-
-    private SmartspaceSubListUiTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
-            @Nullable SmartspaceText titleText,
-            @Nullable SmartspaceIcon titleIcon,
-            @Nullable SmartspaceText subtitleText,
-            @Nullable SmartspaceIcon subTitleIcon,
-            @Nullable SmartspaceTapAction primaryTapAction,
-            @Nullable SmartspaceText supplementalSubtitleText,
-            @Nullable SmartspaceIcon supplementalSubtitleIcon,
-            @Nullable SmartspaceTapAction supplementalSubtitleTapAction,
-            @Nullable SmartspaceText supplementalAlarmText,
-            @Nullable SmartspaceIcon subListIcon,
-            @NonNull List<SmartspaceText> subListTexts,
-            @Nullable SmartspaceTapAction subListAction) {
-        super(templateType, titleText, titleIcon, subtitleText, subTitleIcon, primaryTapAction,
-                supplementalSubtitleText, supplementalSubtitleIcon, supplementalSubtitleTapAction,
-                supplementalAlarmText);
-        mSubListIcon = subListIcon;
-        mSubListTexts = subListTexts;
-        mSubListAction = subListAction;
-    }
-
-    @Nullable
-    public SmartspaceIcon getSubListIcon() {
-        return mSubListIcon;
-    }
-
-    @NonNull
-    public List<SmartspaceText> getSubListTexts() {
-        return mSubListTexts;
-    }
-
-    @Nullable
-    public SmartspaceTapAction getSubListAction() {
-        return mSubListAction;
-    }
-
-    /**
-     * @see Parcelable.Creator
-     */
-    @NonNull
-    public static final Creator<SmartspaceSubListUiTemplateData> CREATOR =
-            new Creator<SmartspaceSubListUiTemplateData>() {
-                @Override
-                public SmartspaceSubListUiTemplateData createFromParcel(Parcel in) {
-                    return new SmartspaceSubListUiTemplateData(in);
-                }
-
-                @Override
-                public SmartspaceSubListUiTemplateData[] newArray(int size) {
-                    return new SmartspaceSubListUiTemplateData[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel out, int flags) {
-        super.writeToParcel(out, flags);
-        out.writeTypedObject(mSubListIcon, flags);
-        out.writeTypedList(mSubListTexts);
-        out.writeTypedObject(mSubListAction, flags);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof SmartspaceSubListUiTemplateData)) return false;
-        if (!super.equals(o)) return false;
-        SmartspaceSubListUiTemplateData that = (SmartspaceSubListUiTemplateData) o;
-        return Objects.equals(mSubListIcon, that.mSubListIcon) && Objects.equals(
-                mSubListTexts, that.mSubListTexts) && Objects.equals(mSubListAction,
-                that.mSubListAction);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(super.hashCode(), mSubListIcon, mSubListTexts, mSubListAction);
-    }
-
-    @Override
-    public String toString() {
-        return super.toString() + " + SmartspaceSubListUiTemplateData{"
-                + "mSubListIcon=" + mSubListIcon
-                + ", mSubListTexts=" + mSubListTexts
-                + ", mSubListAction=" + mSubListAction
-                + '}';
-    }
-
-    /**
-     * A builder for {@link SmartspaceSubListUiTemplateData} object.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final class Builder extends SmartspaceDefaultUiTemplateData.Builder {
-
-        private SmartspaceIcon mSubListIcon;
-        private final List<SmartspaceText> mSubListTexts;
-        private SmartspaceTapAction mSubListAction;
-
-        /**
-         * A builder for {@link SmartspaceSubListUiTemplateData}.
-         */
-        public Builder(@NonNull List<SmartspaceText> subListTexts) {
-            super(SmartspaceTarget.UI_TEMPLATE_SUB_LIST);
-            mSubListTexts = Objects.requireNonNull(subListTexts);
-        }
-
-        /**
-         * Sets the sub-list card icon.
-         */
-        @NonNull
-        public Builder setSubListIcon(@NonNull SmartspaceIcon subListIcon) {
-            mSubListIcon = subListIcon;
-            return this;
-        }
-
-        /**
-         * Sets the card tap action.
-         */
-        @NonNull
-        public Builder setSubListAction(@NonNull SmartspaceTapAction subListAction) {
-            mSubListAction = subListAction;
-            return this;
-        }
-
-        /**
-         * Builds a new SmartspaceSubListUiTemplateData instance.
-         */
-        @NonNull
-        public SmartspaceSubListUiTemplateData build() {
-            return new SmartspaceSubListUiTemplateData(getTemplateType(), getTitleText(),
-                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(), getPrimaryTapAction(),
-                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
-                    getSupplementalSubtitleTapAction(), getSupplementalAlarmText(), mSubListIcon,
-                    mSubListTexts,
-                    mSubListAction);
-        }
-    }
-}
diff --git a/core/java/android/app/smartspace/uitemplatedata/SmartspaceSubCardUiTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/SubCardTemplateData.java
similarity index 60%
rename from core/java/android/app/smartspace/uitemplatedata/SmartspaceSubCardUiTemplateData.java
rename to core/java/android/app/smartspace/uitemplatedata/SubCardTemplateData.java
index 2db13d31..9c8330d 100644
--- a/core/java/android/app/smartspace/uitemplatedata/SmartspaceSubCardUiTemplateData.java
+++ b/core/java/android/app/smartspace/uitemplatedata/SubCardTemplateData.java
@@ -28,43 +28,49 @@
 /**
  * Holds all the relevant data needed to render a Smartspace card with the sub-card Ui Template.
  *
+ * This template will add a sub-card card within the default-template card:
+ * <ul>
+ *     <li> sub-card icon </li>
+ *     <li> sub-card text </li>
+ * </ul>
+ *
  * @hide
  */
 @SystemApi
-public final class SmartspaceSubCardUiTemplateData extends SmartspaceDefaultUiTemplateData {
+public final class SubCardTemplateData extends BaseTemplateData {
 
     /** Icon for the sub-card. */
     @NonNull
-    private final SmartspaceIcon mSubCardIcon;
+    private final Icon mSubCardIcon;
 
     /** Text for the sub-card, which shows below the icon when being set. */
     @Nullable
-    private final SmartspaceText mSubCardText;
+    private final Text mSubCardText;
 
     /** Tap action for the sub-card secondary card. */
     @Nullable
-    private final SmartspaceTapAction mSubCardAction;
+    private final TapAction mSubCardAction;
 
-    SmartspaceSubCardUiTemplateData(@NonNull Parcel in) {
+    SubCardTemplateData(@NonNull Parcel in) {
         super(in);
-        mSubCardIcon = in.readTypedObject(SmartspaceIcon.CREATOR);
-        mSubCardText = in.readTypedObject(SmartspaceText.CREATOR);
-        mSubCardAction = in.readTypedObject(SmartspaceTapAction.CREATOR);
+        mSubCardIcon = in.readTypedObject(Icon.CREATOR);
+        mSubCardText = in.readTypedObject(Text.CREATOR);
+        mSubCardAction = in.readTypedObject(TapAction.CREATOR);
     }
 
-    private SmartspaceSubCardUiTemplateData(int templateType,
-            @Nullable SmartspaceText titleText,
-            @Nullable SmartspaceIcon titleIcon,
-            @Nullable SmartspaceText subtitleText,
-            @Nullable SmartspaceIcon subTitleIcon,
-            @Nullable SmartspaceTapAction primaryTapAction,
-            @Nullable SmartspaceText supplementalSubtitleText,
-            @Nullable SmartspaceIcon supplementalSubtitleIcon,
-            @Nullable SmartspaceTapAction supplementalSubtitleTapAction,
-            @Nullable SmartspaceText supplementalAlarmText,
-            @NonNull SmartspaceIcon subCardIcon,
-            @Nullable SmartspaceText subCardText,
-            @Nullable SmartspaceTapAction subCardAction) {
+    private SubCardTemplateData(int templateType,
+            @Nullable Text titleText,
+            @Nullable Icon titleIcon,
+            @Nullable Text subtitleText,
+            @Nullable Icon subTitleIcon,
+            @Nullable TapAction primaryTapAction,
+            @Nullable Text supplementalSubtitleText,
+            @Nullable Icon supplementalSubtitleIcon,
+            @Nullable TapAction supplementalSubtitleTapAction,
+            @Nullable Text supplementalAlarmText,
+            @NonNull Icon subCardIcon,
+            @Nullable Text subCardText,
+            @Nullable TapAction subCardAction) {
         super(templateType, titleText, titleIcon, subtitleText, subTitleIcon, primaryTapAction,
                 supplementalSubtitleText, supplementalSubtitleIcon, supplementalSubtitleTapAction,
                 supplementalAlarmText);
@@ -73,18 +79,21 @@
         mSubCardAction = subCardAction;
     }
 
+    /** Returns the sub-card card's icon. */
     @NonNull
-    public SmartspaceIcon getSubCardIcon() {
+    public Icon getSubCardIcon() {
         return mSubCardIcon;
     }
 
+    /** Returns the sub-card card's text. */
     @Nullable
-    public SmartspaceText getSubCardText() {
+    public Text getSubCardText() {
         return mSubCardText;
     }
 
+    /** Returns the sub-card card's tap action. */
     @Nullable
-    public SmartspaceTapAction getSubCardAction() {
+    public TapAction getSubCardAction() {
         return mSubCardAction;
     }
 
@@ -92,16 +101,16 @@
      * @see Parcelable.Creator
      */
     @NonNull
-    public static final Creator<SmartspaceSubCardUiTemplateData> CREATOR =
-            new Creator<SmartspaceSubCardUiTemplateData>() {
+    public static final Creator<SubCardTemplateData> CREATOR =
+            new Creator<SubCardTemplateData>() {
                 @Override
-                public SmartspaceSubCardUiTemplateData createFromParcel(Parcel in) {
-                    return new SmartspaceSubCardUiTemplateData(in);
+                public SubCardTemplateData createFromParcel(Parcel in) {
+                    return new SubCardTemplateData(in);
                 }
 
                 @Override
-                public SmartspaceSubCardUiTemplateData[] newArray(int size) {
-                    return new SmartspaceSubCardUiTemplateData[size];
+                public SubCardTemplateData[] newArray(int size) {
+                    return new SubCardTemplateData[size];
                 }
             };
 
@@ -121,9 +130,9 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (!(o instanceof SmartspaceSubCardUiTemplateData)) return false;
+        if (!(o instanceof SubCardTemplateData)) return false;
         if (!super.equals(o)) return false;
-        SmartspaceSubCardUiTemplateData that = (SmartspaceSubCardUiTemplateData) o;
+        SubCardTemplateData that = (SubCardTemplateData) o;
         return mSubCardIcon.equals(that.mSubCardIcon) && SmartspaceUtils.isEqual(mSubCardText,
                 that.mSubCardText) && Objects.equals(mSubCardAction,
                 that.mSubCardAction);
@@ -144,21 +153,21 @@
     }
 
     /**
-     * A builder for {@link SmartspaceSubCardUiTemplateData} object.
+     * A builder for {@link SubCardTemplateData} object.
      *
      * @hide
      */
     @SystemApi
-    public static final class Builder extends SmartspaceDefaultUiTemplateData.Builder {
+    public static final class Builder extends BaseTemplateData.Builder {
 
-        private final SmartspaceIcon mSubCardIcon;
-        private SmartspaceText mSubCardText;
-        private SmartspaceTapAction mSubCardAction;
+        private final Icon mSubCardIcon;
+        private Text mSubCardText;
+        private TapAction mSubCardAction;
 
         /**
-         * A builder for {@link SmartspaceSubCardUiTemplateData}.
+         * A builder for {@link SubCardTemplateData}.
          */
-        public Builder(@NonNull SmartspaceIcon subCardIcon) {
+        public Builder(@NonNull Icon subCardIcon) {
             super(SmartspaceTarget.UI_TEMPLATE_SUB_CARD);
             mSubCardIcon = Objects.requireNonNull(subCardIcon);
         }
@@ -167,7 +176,7 @@
          * Sets the card text.
          */
         @NonNull
-        public Builder setSubCardText(@NonNull SmartspaceText subCardText) {
+        public Builder setSubCardText(@NonNull Text subCardText) {
             mSubCardText = subCardText;
             return this;
         }
@@ -176,7 +185,7 @@
          * Sets the card tap action.
          */
         @NonNull
-        public Builder setSubCardAction(@NonNull SmartspaceTapAction subCardAction) {
+        public Builder setSubCardAction(@NonNull TapAction subCardAction) {
             mSubCardAction = subCardAction;
             return this;
         }
@@ -185,8 +194,8 @@
          * Builds a new SmartspaceSubCardUiTemplateData instance.
          */
         @NonNull
-        public SmartspaceSubCardUiTemplateData build() {
-            return new SmartspaceSubCardUiTemplateData(getTemplateType(), getTitleText(),
+        public SubCardTemplateData build() {
+            return new SubCardTemplateData(getTemplateType(), getTitleText(),
                     getTitleIcon(), getSubtitleText(), getSubtitleIcon(), getPrimaryTapAction(),
                     getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
                     getSupplementalSubtitleTapAction(), getSupplementalAlarmText(), mSubCardIcon,
diff --git a/core/java/android/app/smartspace/uitemplatedata/SubImageTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/SubImageTemplateData.java
new file mode 100644
index 0000000..7df5238
--- /dev/null
+++ b/core/java/android/app/smartspace/uitemplatedata/SubImageTemplateData.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace.uitemplatedata;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.smartspace.SmartspaceTarget;
+import android.os.Parcel;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Holds all the relevant data needed to render a Smartspace card with the sub-image Ui Template.
+ *
+ * This template will add a sub-image card within the default-template card:
+ * <ul>
+ *     <li> sub-image text1 </li>   <ul>
+ *     <li> sub-image text2 </li>        image (can be a GIF)
+ *     ...                          </ul>
+ * </ul>
+ *
+ * @hide
+ */
+@SystemApi
+public final class SubImageTemplateData extends BaseTemplateData {
+
+    /** Texts are shown next to the image as a vertical list */
+    @NonNull
+    private final List<Text> mSubImageTexts;
+
+    /** If multiple images are passed in, they will be rendered as GIF. */
+    @NonNull
+    private final List<Icon> mSubImages;
+
+    /** Tap action for the sub-image secondary card. */
+    @Nullable
+    private final TapAction mSubImageAction;
+
+    SubImageTemplateData(@NonNull Parcel in) {
+        super(in);
+        mSubImageTexts = in.createTypedArrayList(Text.CREATOR);
+        mSubImages = in.createTypedArrayList(Icon.CREATOR);
+        mSubImageAction = in.readTypedObject(TapAction.CREATOR);
+    }
+
+    private SubImageTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
+            @Nullable Text titleText,
+            @Nullable Icon titleIcon,
+            @Nullable Text subtitleText,
+            @Nullable Icon subTitleIcon,
+            @Nullable TapAction primaryTapAction,
+            @Nullable Text supplementalSubtitleText,
+            @Nullable Icon supplementalSubtitleIcon,
+            @Nullable TapAction supplementalSubtitleTapAction,
+            @Nullable Text supplementalAlarmText,
+            @NonNull List<Text> subImageTexts,
+            @NonNull List<Icon> subImages,
+            @Nullable TapAction subImageAction) {
+        super(templateType, titleText, titleIcon, subtitleText, subTitleIcon, primaryTapAction,
+                supplementalSubtitleText, supplementalSubtitleIcon, supplementalSubtitleTapAction,
+                supplementalAlarmText);
+        mSubImageTexts = subImageTexts;
+        mSubImages = subImages;
+        mSubImageAction = subImageAction;
+    }
+
+    /** Returns the list of sub-image card's texts. Can be empty if not being set. */
+    @NonNull
+    public List<Text> getSubImageTexts() {
+        return mSubImageTexts;
+    }
+
+    /**
+     * Returns the list of sub-image card's image. It's a single-element list if it's a static
+     * image, or a multi-elements list if it's a GIF.
+     */
+    @NonNull
+    public List<Icon> getSubImages() {
+        return mSubImages;
+    }
+
+    /** Returns the sub-image card's tap action. */
+    @Nullable
+    public TapAction getSubImageAction() {
+        return mSubImageAction;
+    }
+
+    /**
+     * @see Parcelable.Creator
+     */
+    @NonNull
+    public static final Creator<SubImageTemplateData> CREATOR =
+            new Creator<SubImageTemplateData>() {
+                @Override
+                public SubImageTemplateData createFromParcel(Parcel in) {
+                    return new SubImageTemplateData(in);
+                }
+
+                @Override
+                public SubImageTemplateData[] newArray(int size) {
+                    return new SubImageTemplateData[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        super.writeToParcel(out, flags);
+        out.writeTypedList(mSubImageTexts);
+        out.writeTypedList(mSubImages);
+        out.writeTypedObject(mSubImageAction, flags);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof SubImageTemplateData)) return false;
+        if (!super.equals(o)) return false;
+        SubImageTemplateData that = (SubImageTemplateData) o;
+        return Objects.equals(mSubImageTexts, that.mSubImageTexts)
+                && Objects.equals(mSubImages, that.mSubImages) && Objects.equals(
+                mSubImageAction, that.mSubImageAction);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), mSubImageTexts, mSubImages, mSubImageAction);
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + " + SmartspaceSubImageUiTemplateData{"
+                + "mSubImageTexts=" + mSubImageTexts
+                + ", mSubImages=" + mSubImages
+                + ", mSubImageAction=" + mSubImageAction
+                + '}';
+    }
+
+    /**
+     * A builder for {@link SubImageTemplateData} object.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class Builder extends BaseTemplateData.Builder {
+
+        private final List<Text> mSubImageTexts;
+        private final List<Icon> mSubImages;
+        private TapAction mSubImageAction;
+
+        /**
+         * A builder for {@link SubImageTemplateData}.
+         */
+        public Builder(@NonNull List<Text> subImageTexts,
+                @NonNull List<Icon> subImages) {
+            super(SmartspaceTarget.UI_TEMPLATE_SUB_IMAGE);
+            mSubImageTexts = Objects.requireNonNull(subImageTexts);
+            mSubImages = Objects.requireNonNull(subImages);
+        }
+
+        /**
+         * Sets the card tap action.
+         */
+        @NonNull
+        public Builder setSubImageAction(@NonNull TapAction subImageAction) {
+            mSubImageAction = subImageAction;
+            return this;
+        }
+
+        /**
+         * Builds a new SmartspaceSubImageUiTemplateData instance.
+         */
+        @NonNull
+        public SubImageTemplateData build() {
+            return new SubImageTemplateData(getTemplateType(), getTitleText(),
+                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(), getPrimaryTapAction(),
+                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
+                    getSupplementalSubtitleTapAction(), getSupplementalAlarmText(), mSubImageTexts,
+                    mSubImages,
+                    mSubImageAction);
+        }
+    }
+}
diff --git a/core/java/android/app/smartspace/uitemplatedata/SubListTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/SubListTemplateData.java
new file mode 100644
index 0000000..6f6034d
--- /dev/null
+++ b/core/java/android/app/smartspace/uitemplatedata/SubListTemplateData.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace.uitemplatedata;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.smartspace.SmartspaceTarget;
+import android.os.Parcel;
+
+import java.util.List;
+import java.util.Objects;
+
+
+/**
+ * Holds all the relevant data needed to render a Smartspace card with the sub-list Ui Template.
+ *
+ * This template will add a sub-list card within the default-template card:
+ * <ul>
+ *     <li> sub-list text1       sub-list icon </li>
+ *     <li> sub-list text2 </li>
+ *     <li> sub-list text3 </li>
+ *     ...
+ * </ul>
+ *
+ * @hide
+ */
+@SystemApi
+public final class SubListTemplateData extends BaseTemplateData {
+
+    @Nullable
+    private final Icon mSubListIcon;
+    @NonNull
+    private final List<Text> mSubListTexts;
+
+    /** Tap action for the sub-list secondary card. */
+    @Nullable
+    private final TapAction mSubListAction;
+
+    SubListTemplateData(@NonNull Parcel in) {
+        super(in);
+        mSubListIcon = in.readTypedObject(Icon.CREATOR);
+        mSubListTexts = in.createTypedArrayList(Text.CREATOR);
+        mSubListAction = in.readTypedObject(TapAction.CREATOR);
+    }
+
+    private SubListTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
+            @Nullable Text titleText,
+            @Nullable Icon titleIcon,
+            @Nullable Text subtitleText,
+            @Nullable Icon subTitleIcon,
+            @Nullable TapAction primaryTapAction,
+            @Nullable Text supplementalSubtitleText,
+            @Nullable Icon supplementalSubtitleIcon,
+            @Nullable TapAction supplementalSubtitleTapAction,
+            @Nullable Text supplementalAlarmText,
+            @Nullable Icon subListIcon,
+            @NonNull List<Text> subListTexts,
+            @Nullable TapAction subListAction) {
+        super(templateType, titleText, titleIcon, subtitleText, subTitleIcon, primaryTapAction,
+                supplementalSubtitleText, supplementalSubtitleIcon, supplementalSubtitleTapAction,
+                supplementalAlarmText);
+        mSubListIcon = subListIcon;
+        mSubListTexts = subListTexts;
+        mSubListAction = subListAction;
+    }
+
+    /** Returns the sub-list card's icon. */
+    @Nullable
+    public Icon getSubListIcon() {
+        return mSubListIcon;
+    }
+
+    /** Returns the sub-list card's texts list. */
+    @NonNull
+    public List<Text> getSubListTexts() {
+        return mSubListTexts;
+    }
+
+    /** Returns the sub-list card's tap action. */
+    @Nullable
+    public TapAction getSubListAction() {
+        return mSubListAction;
+    }
+
+    /**
+     * @see Parcelable.Creator
+     */
+    @NonNull
+    public static final Creator<SubListTemplateData> CREATOR =
+            new Creator<SubListTemplateData>() {
+                @Override
+                public SubListTemplateData createFromParcel(Parcel in) {
+                    return new SubListTemplateData(in);
+                }
+
+                @Override
+                public SubListTemplateData[] newArray(int size) {
+                    return new SubListTemplateData[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        super.writeToParcel(out, flags);
+        out.writeTypedObject(mSubListIcon, flags);
+        out.writeTypedList(mSubListTexts);
+        out.writeTypedObject(mSubListAction, flags);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof SubListTemplateData)) return false;
+        if (!super.equals(o)) return false;
+        SubListTemplateData that = (SubListTemplateData) o;
+        return Objects.equals(mSubListIcon, that.mSubListIcon) && Objects.equals(
+                mSubListTexts, that.mSubListTexts) && Objects.equals(mSubListAction,
+                that.mSubListAction);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), mSubListIcon, mSubListTexts, mSubListAction);
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + " + SmartspaceSubListUiTemplateData{"
+                + "mSubListIcon=" + mSubListIcon
+                + ", mSubListTexts=" + mSubListTexts
+                + ", mSubListAction=" + mSubListAction
+                + '}';
+    }
+
+    /**
+     * A builder for {@link SubListTemplateData} object.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class Builder extends BaseTemplateData.Builder {
+
+        private Icon mSubListIcon;
+        private final List<Text> mSubListTexts;
+        private TapAction mSubListAction;
+
+        /**
+         * A builder for {@link SubListTemplateData}.
+         */
+        public Builder(@NonNull List<Text> subListTexts) {
+            super(SmartspaceTarget.UI_TEMPLATE_SUB_LIST);
+            mSubListTexts = Objects.requireNonNull(subListTexts);
+        }
+
+        /**
+         * Sets the sub-list card icon.
+         */
+        @NonNull
+        public Builder setSubListIcon(@NonNull Icon subListIcon) {
+            mSubListIcon = subListIcon;
+            return this;
+        }
+
+        /**
+         * Sets the card tap action.
+         */
+        @NonNull
+        public Builder setSubListAction(@NonNull TapAction subListAction) {
+            mSubListAction = subListAction;
+            return this;
+        }
+
+        /**
+         * Builds a new SmartspaceSubListUiTemplateData instance.
+         */
+        @NonNull
+        public SubListTemplateData build() {
+            return new SubListTemplateData(getTemplateType(), getTitleText(),
+                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(), getPrimaryTapAction(),
+                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
+                    getSupplementalSubtitleTapAction(), getSupplementalAlarmText(), mSubListIcon,
+                    mSubListTexts,
+                    mSubListAction);
+        }
+    }
+}
diff --git a/core/java/android/app/smartspace/uitemplatedata/SmartspaceTapAction.java b/core/java/android/app/smartspace/uitemplatedata/TapAction.java
similarity index 81%
rename from core/java/android/app/smartspace/uitemplatedata/SmartspaceTapAction.java
rename to core/java/android/app/smartspace/uitemplatedata/TapAction.java
index 27d8e5f..83ff6ab 100644
--- a/core/java/android/app/smartspace/uitemplatedata/SmartspaceTapAction.java
+++ b/core/java/android/app/smartspace/uitemplatedata/TapAction.java
@@ -33,7 +33,7 @@
 import java.util.Objects;
 
 /**
- * A {@link SmartspaceTapAction} represents an action which can be taken by a user by tapping on
+ * A {@link TapAction} represents an action which can be taken by a user by tapping on
  * either the title, the subtitle or on the icon. Supported instances are Intents and
  * PendingIntents. These actions can be called from another process or within the client process.
  *
@@ -42,9 +42,9 @@
  * @hide
  */
 @SystemApi
-public final class SmartspaceTapAction implements Parcelable {
+public final class TapAction implements Parcelable {
 
-    /** A unique Id of this {@link SmartspaceTapAction}. */
+    /** A unique Id of this {@link TapAction}. */
     @Nullable
     private final CharSequence mId;
 
@@ -60,7 +60,7 @@
     @Nullable
     private Bundle mExtras;
 
-    SmartspaceTapAction(@NonNull Parcel in) {
+    TapAction(@NonNull Parcel in) {
         mId = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mIntent = in.readTypedObject(Intent.CREATOR);
         mPendingIntent = in.readTypedObject(PendingIntent.CREATOR);
@@ -68,7 +68,7 @@
         mExtras = in.readBundle();
     }
 
-    private SmartspaceTapAction(@Nullable CharSequence id, @Nullable Intent intent,
+    private TapAction(@Nullable CharSequence id, @Nullable Intent intent,
             @Nullable PendingIntent pendingIntent, @Nullable UserHandle userHandle,
             @Nullable Bundle extras) {
         mId = id;
@@ -78,27 +78,32 @@
         mExtras = extras;
     }
 
+    /** Returns the unique id of the tap action. */
     @Nullable
     public CharSequence getId() {
         return mId;
     }
 
+    /** Returns the intent of the tap action. */
     @SuppressLint("IntentBuilderName")
     @Nullable
     public Intent getIntent() {
         return mIntent;
     }
 
+    /** Returns the pending intent of the tap action. */
     @Nullable
     public PendingIntent getPendingIntent() {
         return mPendingIntent;
     }
 
+    /** Returns the user handle of the tap action. */
     @Nullable
     public UserHandle getUserHandle() {
         return mUserHandle;
     }
 
+    /** Returns the extras bundle of the tap action. */
     @Nullable
     @SuppressLint("NullableCollection")
     public Bundle getExtras() {
@@ -120,23 +125,23 @@
     }
 
     @NonNull
-    public static final Creator<SmartspaceTapAction> CREATOR = new Creator<SmartspaceTapAction>() {
+    public static final Creator<TapAction> CREATOR = new Creator<TapAction>() {
         @Override
-        public SmartspaceTapAction createFromParcel(Parcel in) {
-            return new SmartspaceTapAction(in);
+        public TapAction createFromParcel(Parcel in) {
+            return new TapAction(in);
         }
 
         @Override
-        public SmartspaceTapAction[] newArray(int size) {
-            return new SmartspaceTapAction[size];
+        public TapAction[] newArray(int size) {
+            return new TapAction[size];
         }
     };
 
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (!(o instanceof SmartspaceTapAction)) return false;
-        SmartspaceTapAction that = (SmartspaceTapAction) o;
+        if (!(o instanceof TapAction)) return false;
+        TapAction that = (TapAction) o;
         return SmartspaceUtils.isEqual(mId, that.mId);
     }
 
@@ -157,7 +162,7 @@
     }
 
     /**
-     * A builder for {@link SmartspaceTapAction} object.
+     * A builder for {@link TapAction} object.
      *
      * @hide
      */
@@ -171,9 +176,9 @@
         private Bundle mExtras;
 
         /**
-         * A builder for {@link SmartspaceTapAction}.
+         * A builder for {@link TapAction}.
          *
-         * @param id A unique Id of this {@link SmartspaceTapAction}.
+         * @param id A unique Id of this {@link TapAction}.
          */
         public Builder(@NonNull CharSequence id) {
             mId = Objects.requireNonNull(id);
@@ -222,11 +227,11 @@
          * @throws IllegalStateException if the tap action is empty.
          */
         @NonNull
-        public SmartspaceTapAction build() {
+        public TapAction build() {
             if (mIntent == null && mPendingIntent == null && mExtras == null) {
                 throw new IllegalStateException("Please assign at least 1 valid tap field");
             }
-            return new SmartspaceTapAction(mId, mIntent, mPendingIntent, mUserHandle, mExtras);
+            return new TapAction(mId, mIntent, mPendingIntent, mUserHandle, mExtras);
         }
     }
 }
diff --git a/core/java/android/app/smartspace/uitemplatedata/SmartspaceText.java b/core/java/android/app/smartspace/uitemplatedata/Text.java
similarity index 63%
rename from core/java/android/app/smartspace/uitemplatedata/SmartspaceText.java
rename to core/java/android/app/smartspace/uitemplatedata/Text.java
index 25d13e6..b733394 100644
--- a/core/java/android/app/smartspace/uitemplatedata/SmartspaceText.java
+++ b/core/java/android/app/smartspace/uitemplatedata/Text.java
@@ -32,43 +32,54 @@
  * @hide
  */
 @SystemApi
-public final class SmartspaceText implements Parcelable {
+public final class Text implements Parcelable {
 
     @NonNull
     private final CharSequence mText;
 
     private final TextUtils.TruncateAt mTruncateAtType;
 
-    SmartspaceText(Parcel in) {
+    private final int mMaxLines;
+
+    Text(Parcel in) {
         mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mTruncateAtType = TextUtils.TruncateAt.valueOf(in.readString());
+        mMaxLines = in.readInt();
     }
 
-    private SmartspaceText(@NonNull CharSequence text, TextUtils.TruncateAt truncateAtType) {
+    private Text(@NonNull CharSequence text, TextUtils.TruncateAt truncateAtType, int maxLines) {
         mText = text;
         mTruncateAtType = truncateAtType;
+        mMaxLines = maxLines;
     }
 
+    /** Returns the text content. */
     @NonNull
     public CharSequence getText() {
         return mText;
     }
 
+    /** Returns the {@link TextUtils.TruncateAt} type of the text content. */
     @NonNull
     public TextUtils.TruncateAt getTruncateAtType() {
         return mTruncateAtType;
     }
 
+    /** Returns the allowed max lines for presenting the text content. */
+    public int getMaxLines() {
+        return mMaxLines;
+    }
+
     @NonNull
-    public static final Creator<SmartspaceText> CREATOR = new Creator<SmartspaceText>() {
+    public static final Creator<Text> CREATOR = new Creator<Text>() {
         @Override
-        public SmartspaceText createFromParcel(Parcel in) {
-            return new SmartspaceText(in);
+        public Text createFromParcel(Parcel in) {
+            return new Text(in);
         }
 
         @Override
-        public SmartspaceText[] newArray(int size) {
-            return new SmartspaceText[size];
+        public Text[] newArray(int size) {
+            return new Text[size];
         }
     };
 
@@ -80,25 +91,26 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (!(o instanceof SmartspaceText)) return false;
-        SmartspaceText that = (SmartspaceText) o;
+        if (!(o instanceof Text)) return false;
+        Text that = (Text) o;
         return mTruncateAtType == that.mTruncateAtType && SmartspaceUtils.isEqual(mText,
-                that.mText);
+                that.mText) && mMaxLines == that.mMaxLines;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mText, mTruncateAtType);
+        return Objects.hash(mText, mTruncateAtType, mMaxLines);
     }
 
     @Override
     public void writeToParcel(@NonNull Parcel out, int flags) {
         TextUtils.writeToParcel(mText, out, flags);
         out.writeString(mTruncateAtType.name());
+        out.writeInt(mMaxLines);
     }
 
     /**
-     * A builder for {@link SmartspaceText} object.
+     * A builder for {@link Text} object.
      *
      * @hide
      */
@@ -106,25 +118,31 @@
     public static final class Builder {
         private final CharSequence mText;
         private TextUtils.TruncateAt mTruncateAtType;
+        private int mMaxLines;
 
         /**
-         * A builder for {@link SmartspaceText}, which sets TruncateAtType to AT_END by default.
+         * A builder for {@link Text}, which by default sets TruncateAtType to AT_END, and the max
+         * lines to 1.
          */
         public Builder(@NonNull CharSequence text) {
             mText = Objects.requireNonNull(text);
             mTruncateAtType = TextUtils.TruncateAt.END;
+            mMaxLines = 1;
         }
 
         /**
-         * A builder for {@link SmartspaceText}.
+         * A builder for {@link Text} with specifying {@link TextUtils.TruncateAt} type, and by
+         * default set the max lines to 1.
          */
         public Builder(@NonNull CharSequence text, @NonNull TextUtils.TruncateAt truncateAtType) {
             mText = Objects.requireNonNull(text);
             mTruncateAtType = Objects.requireNonNull(truncateAtType);
+            mMaxLines = 1;
         }
 
         /**
-         * Sets truncateAtType.
+         * Sets truncateAtType, where the text content should be truncated if not all the content
+         * can be presented.
          */
         @NonNull
         public Builder setTruncateAtType(@NonNull TextUtils.TruncateAt truncateAtType) {
@@ -133,11 +151,20 @@
         }
 
         /**
+         * Sets the allowed max lines for the text content.
+         */
+        @NonNull
+        public Builder setMaxLines(int maxLines) {
+            mMaxLines = maxLines;
+            return this;
+        }
+
+        /**
          * Builds a new SmartspaceText instance.
          */
         @NonNull
-        public SmartspaceText build() {
-            return new SmartspaceText(mText, mTruncateAtType);
+        public Text build() {
+            return new Text(mText, mTruncateAtType, mMaxLines);
         }
     }
 }
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index f1abb05..d50a6ba 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -82,14 +82,21 @@
     }
 
     /**
-     * Creates a virtual device.
+     * Creates a virtual device where applications can launch and receive input events injected by
+     * the creator.
+     *
+     * <p>The {@link android.Manifest.permission#CREATE_VIRTUAL_DEVICE} permission is required to
+     * create virtual devices, which is only available to system apps holding specific roles.
      *
      * @param associationId The association ID as returned by {@link AssociationInfo#getId()} from
      *   Companion Device Manager. Virtual devices must have a corresponding association with CDM in
      *   order to be created.
+     * @param params The parameters for creating virtual devices. See {@link VirtualDeviceParams}
+     *   for the available options.
+     * @return The created virtual device.
      */
     @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-    @Nullable
+    @NonNull
     public VirtualDevice createVirtualDevice(
             int associationId,
             @NonNull VirtualDeviceParams params) {
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 971b61b..c053c92 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -356,7 +356,6 @@
      * @see #VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
      * @hide
      */
-    @TestApi
     @SystemApi
     public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1 << 10;
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ea20ed4..23e02e9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11720,8 +11720,8 @@
                 "night_display_forced_auto_mode_available";
 
         /**
-         * If UTC time between two NITZ signals is greater than this value then the second signal
-         * cannot be ignored.
+         * If Unix epoch time between two NITZ signals is greater than this value then the second
+         * signal cannot be ignored.
          *
          * <p>This value is in milliseconds. It is used for telephony-based time and time zone
          * detection.
@@ -16865,6 +16865,14 @@
                 "system_server_watchdog_timeout_ms";
 
         /**
+         * Whether to enable managed device provisioning via the role holder.
+         *
+         * @hide
+         */
+        public static final String MANAGED_PROVISIONING_DEFER_PROVISIONING_TO_ROLE_HOLDER =
+                "managed_provisioning_defer_provisioning_to_role_holder";
+
+        /**
          * Settings migrated from Wear OS settings provider.
          * @hide
          */
diff --git a/core/java/android/util/OWNERS b/core/java/android/util/OWNERS
index 28c078e..d4cf6e6 100644
--- a/core/java/android/util/OWNERS
+++ b/core/java/android/util/OWNERS
@@ -6,3 +6,7 @@
 per-file TypedValue.java = file:/core/java/android/content/res/OWNERS
 
 per-file PackageUtils.java = file:/core/java/android/content/pm/OWNERS
+
+per-file NtpTrustedTime.java = file:/services/core/java/com/android/server/timezonedetector/OWNERS
+per-file TimeUtils.java = file:/services/core/java/com/android/server/timezonedetector/OWNERS
+per-file TrustedTime.java = file:/services/core/java/com/android/server/timezonedetector/OWNERS
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index 5fd0c33..9a93e1b 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -153,8 +153,8 @@
      *
      * <p>Time zone database updates should be expected to occur periodically due to
      * political and legal changes that cannot be anticipated in advance.  Therefore,
-     * when computing the UTC time for a future event, applications should be aware that
-     * the results may differ following a time zone database update.  This method allows
+     * when computing the time for a future event, applications should be aware that the
+     * results may differ following a time zone database update.  This method allows
      * applications to detect that a database change has occurred, and to recalculate any
      * cached times accordingly.
      *
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 73d2d8d..8c33e07 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -63,12 +63,94 @@
 static PlaybackParams::fields_t gPlaybackParamsFields;
 static VolumeShaperHelper::fields_t gVolumeShaperFields;
 
-struct audiotrack_callback_cookie {
-    jclass      audioTrack_class;
-    jobject     audioTrack_ref;
-    bool        busy;
-    Condition   cond;
-    bool        isOffload;
+class AudioTrackCallbackImpl : public AudioTrack::IAudioTrackCallback {
+  public:
+    enum event_type {
+    // Keep in sync with java
+        EVENT_MORE_DATA = 0,
+        EVENT_UNDERRUN = 1,
+        EVENT_LOOP_END = 2,
+        EVENT_MARKER = 3,
+        EVENT_NEW_POS = 4,
+        EVENT_BUFFER_END = 5,
+        EVENT_NEW_IAUDIOTRACK = 6,
+        EVENT_STREAM_END = 7,
+        // 8 is reserved for future use
+        EVENT_CAN_WRITE_MORE_DATA = 9
+    };
+
+    AudioTrackCallbackImpl(jclass audioTrackClass, jobject audioTrackWeakRef, bool isOffload)
+          : mIsOffload(isOffload)
+    {
+      const auto env = getJNIEnv();
+      mAudioTrackClass = (jclass)env->NewGlobalRef(audioTrackClass);
+      // we use a weak reference so the AudioTrack object can be garbage collected.
+      mAudioTrackWeakRef = env->NewGlobalRef(audioTrackWeakRef);
+
+    }
+
+    AudioTrackCallbackImpl(const AudioTrackCallbackImpl&) = delete;
+    AudioTrackCallbackImpl& operator=(const AudioTrackCallbackImpl&) = delete;
+    ~AudioTrackCallbackImpl() {
+        const auto env = getJNIEnv();
+        env->DeleteGlobalRef(mAudioTrackClass);
+        env->DeleteGlobalRef(mAudioTrackWeakRef);
+    }
+
+    size_t onCanWriteMoreData(const AudioTrack::Buffer& buffer) override {
+      if (!mIsOffload) {
+          LOG_FATAL("Received canWrite callback for non-offload track");
+          return 0;
+      }
+      const size_t availableForWrite = buffer.size();
+      const int arg = availableForWrite > INT32_MAX ? INT32_MAX : (int) availableForWrite;
+      postEvent(EVENT_CAN_WRITE_MORE_DATA, arg);
+      return 0;
+    }
+
+    void onMarker([[maybe_unused]] uint32_t markerPosition) override {
+        postEvent(EVENT_MARKER);
+    }
+    void onNewPos([[maybe_unused]] uint32_t newPos) override {
+        postEvent(EVENT_NEW_POS);
+    }
+
+
+    void onNewIAudioTrack() override {
+        if (!mIsOffload) return;
+        postEvent(EVENT_NEW_IAUDIOTRACK);
+    }
+
+    void onStreamEnd() override {
+        if (!mIsOffload) return;
+        postEvent(EVENT_STREAM_END);
+    }
+
+  protected:
+    jobject     mAudioTrackWeakRef;
+  private:
+     JNIEnv* getJNIEnv() {
+          auto jni = AndroidRuntime::getJNIEnv();
+          if (jni == nullptr) {
+              LOG_ALWAYS_FATAL("AudioTrackCallback thread JNI reference is null");
+          }
+          return jni;
+     }
+
+     void postEvent(int event, int arg = 0) {
+        auto env = getJNIEnv();
+        env->CallStaticVoidMethod(
+                mAudioTrackClass,
+                javaAudioTrackFields.postNativeEventInJava,
+                mAudioTrackWeakRef, event, arg, 0, NULL);
+        if (env->ExceptionCheck()) {
+            env->ExceptionDescribe();
+            env->ExceptionClear();
+        }
+    }
+
+    jclass      mAudioTrackClass;
+    const bool  mIsOffload;
 };
 
 // keep these values in sync with AudioTrack.java
@@ -76,22 +158,21 @@
 #define MODE_STREAM 1
 
 // ----------------------------------------------------------------------------
-class AudioTrackJniStorage {
+class AudioTrackJniStorage : public virtual RefBase,
+                             public AudioTrackCallbackImpl
+{
 public:
-    sp<MemoryHeapBase> mMemHeap;
-    sp<MemoryBase> mMemBase;
-    audiotrack_callback_cookie mCallbackData{};
+    // TODO do we always want to initialize the callback implementation?
+    AudioTrackJniStorage(jclass audioTrackClass, jobject audioTrackRef, bool isOffload = false)
+          : AudioTrackCallbackImpl(audioTrackClass, audioTrackRef, isOffload) {}
+
     sp<JNIDeviceCallback> mDeviceCallback;
     sp<JNIAudioTrackCallback> mAudioTrackCallback;
 
-    bool allocSharedMem(int sizeInBytes) {
-        mMemHeap = new MemoryHeapBase(sizeInBytes, 0, "AudioTrack Heap Base");
-        if (mMemHeap->getHeapID() < 0) {
-            return false;
-        }
-        mMemBase = new MemoryBase(mMemHeap, 0, sizeInBytes);
-        return true;
+    jobject getAudioTrackWeakRef() const {
+        return mAudioTrackWeakRef;
     }
+
 };
 
 class TunerConfigurationHelper {
@@ -136,7 +217,6 @@
 };
 
 static Mutex sLock;
-static SortedVector <audiotrack_callback_cookie *> sAudioTrackCallBackCookies;
 
 // ----------------------------------------------------------------------------
 #define DEFAULT_OUTPUT_SAMPLE_RATE   44100
@@ -147,102 +227,49 @@
 #define AUDIOTRACK_ERROR_SETUP_INVALIDSTREAMTYPE   (-19)
 #define AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED    (-20)
 
-// ----------------------------------------------------------------------------
-static void audioCallback(int event, void* user, void *info) {
-
-    audiotrack_callback_cookie *callbackInfo = (audiotrack_callback_cookie *)user;
-    {
-        Mutex::Autolock l(sLock);
-        if (sAudioTrackCallBackCookies.indexOf(callbackInfo) < 0) {
-            return;
-        }
-        callbackInfo->busy = true;
+namespace {
+sp<IMemory> allocSharedMem(int sizeInBytes) {
+    const auto heap = sp<MemoryHeapBase>::make(sizeInBytes, 0, "AudioTrack Heap Base");
+    if (heap->getBase() == MAP_FAILED || heap->getBase() == nullptr) {
+        return nullptr;
     }
-
-    // used as default argument when event callback doesn't have any, or number of
-    // frames for EVENT_CAN_WRITE_MORE_DATA
-    int arg = 0;
-    bool postEvent = false;
-    switch (event) {
-    // Offload only events
-    case AudioTrack::EVENT_CAN_WRITE_MORE_DATA:
-        // this event will read the info return parameter of the callback:
-        // for JNI offload, use the returned size to indicate:
-        // 1/ no data is returned through callback, as it's all done through write()
-        // 2/ do not wait as AudioTrack does when it receives 0 bytes
-        if (callbackInfo->isOffload) {
-            AudioTrack::Buffer* pBuffer = (AudioTrack::Buffer*) info;
-            const size_t availableForWrite = pBuffer->size;
-            arg = availableForWrite > INT32_MAX ? INT32_MAX : (int) availableForWrite;
-            pBuffer->size = 0;
-        }
-        FALLTHROUGH_INTENDED;
-    case AudioTrack::EVENT_STREAM_END:
-    case AudioTrack::EVENT_NEW_IAUDIOTRACK: // a.k.a. tear down
-        if (callbackInfo->isOffload) {
-            postEvent = true;
-        }
-        break;
-
-    // PCM and offload events
-    case AudioTrack::EVENT_MARKER:
-    case AudioTrack::EVENT_NEW_POS:
-        postEvent = true;
-        break;
-    default:
-        // event will not be posted
-        break;
-    }
-
-    if (postEvent) {
-        JNIEnv *env = AndroidRuntime::getJNIEnv();
-        if (env != NULL) {
-            env->CallStaticVoidMethod(
-                    callbackInfo->audioTrack_class,
-                    javaAudioTrackFields.postNativeEventInJava,
-                    callbackInfo->audioTrack_ref, event, arg, 0, NULL);
-            if (env->ExceptionCheck()) {
-                env->ExceptionDescribe();
-                env->ExceptionClear();
-            }
-        }
-    }
-
-    {
-        Mutex::Autolock l(sLock);
-        callbackInfo->busy = false;
-        callbackInfo->cond.broadcast();
-    }
+    return sp<MemoryBase>::make(heap, 0, sizeInBytes);
+}
+// TODO(b/218351957) move somewhere?
+template<typename T>
+sp<T> getFieldSp(JNIEnv* env, jobject thiz, jfieldID id)
+{
+    // make these fields atomic longs on the java side
+    Mutex::Autolock l(sLock);
+    return sp<T>::fromExisting(reinterpret_cast<T*>(env->GetLongField(thiz, id)));
 }
 
-
-// ----------------------------------------------------------------------------
-static sp<AudioTrack> getAudioTrack(JNIEnv* env, jobject thiz)
+// This (semantically) should only be called on AudioTrack creation and release
+template <typename T>
+sp<T> setFieldSp(JNIEnv* env, jobject thiz, const sp<T>& at, jfieldID id)
 {
     Mutex::Autolock l(sLock);
-    AudioTrack* const at =
-            (AudioTrack*)env->GetLongField(thiz, javaAudioTrackFields.nativeTrackInJavaObj);
-    return sp<AudioTrack>(at);
-}
-
-static sp<AudioTrack> setAudioTrack(JNIEnv* env, jobject thiz, const sp<AudioTrack>& at)
-{
-    Mutex::Autolock l(sLock);
-    sp<AudioTrack> old =
-            (AudioTrack*)env->GetLongField(thiz, javaAudioTrackFields.nativeTrackInJavaObj);
+    // I don't think this synchronization actually prevents a race
+    // We can still invalidate under our feet in release
+    sp<T> old = sp<T>::fromExisting(reinterpret_cast<T*>(env->GetLongField(thiz, id)));
     if (at.get()) {
-        at->incStrong((void*)setAudioTrack);
+        at->incStrong((void*)setFieldSp<T>);
     }
     if (old != 0) {
-        old->decStrong((void*)setAudioTrack);
+        old->decStrong((void*)setFieldSp<T>);
     }
-    env->SetLongField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, (jlong)at.get());
+    env->SetLongField(thiz, id, (jlong)at.get());
     return old;
 }
 
+sp<AudioTrack> getAudioTrack(JNIEnv* env, jobject thiz) {
+    return getFieldSp<AudioTrack>(env, thiz, javaAudioTrackFields.nativeTrackInJavaObj);
+}
+
+} // anonymous
 // ----------------------------------------------------------------------------
 sp<AudioTrack> android_media_AudioTrack_getAudioTrack(JNIEnv* env, jobject audioTrackObj) {
-    return getAudioTrack(env, audioTrackObj);
+    return getFieldSp<AudioTrack>(env, audioTrackObj, javaAudioTrackFields.nativeTrackInJavaObj);
 }
 
 // ----------------------------------------------------------------------------
@@ -274,7 +301,6 @@
     env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
     nSession = NULL;
 
-    AudioTrackJniStorage* lpJniStorage = NULL;
 
     jclass clazz = env->GetObjectClass(thiz);
     if (clazz == NULL) {
@@ -284,6 +310,7 @@
 
     // if we pass in an existing *Native* AudioTrack, we don't need to create/initialize one.
     sp<AudioTrack> lpTrack;
+    const auto lpJniStorage = sp<AudioTrackJniStorage>::make(clazz, weak_this, offload);
     if (nativeAudioTrack == 0) {
         if (jaa == 0) {
             ALOGE("Error creating AudioTrack: invalid audio attributes");
@@ -332,7 +359,7 @@
         AttributionSourceState attributionSource;
         attributionSource.packageName = std::string(opPackageNameStr.c_str());
         attributionSource.token = sp<BBinder>::make();
-        lpTrack = new AudioTrack(attributionSource);
+        lpTrack = sp<AudioTrack>::make(attributionSource);
 
         // read the AudioAttributes values
         auto paa = JNIAudioAttributeHelper::makeUnique();
@@ -345,13 +372,6 @@
 
         // initialize the callback information:
         // this data will be passed with every AudioTrack callback
-        lpJniStorage = new AudioTrackJniStorage();
-        lpJniStorage->mCallbackData.audioTrack_class = (jclass)env->NewGlobalRef(clazz);
-        // we use a weak reference so the AudioTrack object can be garbage collected.
-        lpJniStorage->mCallbackData.audioTrack_ref = env->NewGlobalRef(weak_this);
-        lpJniStorage->mCallbackData.isOffload = offload;
-        lpJniStorage->mCallbackData.busy = false;
-
         audio_offload_info_t offloadInfo;
         if (offload == JNI_TRUE) {
             offloadInfo = AUDIO_INFO_INITIALIZER;
@@ -385,8 +405,7 @@
                                   nativeChannelMask, offload ? 0 : frameCount,
                                   offload ? AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD
                                           : AUDIO_OUTPUT_FLAG_NONE,
-                                  audioCallback,
-                                  &(lpJniStorage->mCallbackData), // callback, callback data (user)
+                                  lpJniStorage,
                                   0,    // notificationFrames == 0 since not using EVENT_MORE_DATA
                                         // to feed the AudioTrack
                                   0,    // shared mem
@@ -400,9 +419,10 @@
             break;
 
         case MODE_STATIC:
+        {
             // AudioTrack is using shared memory
-
-            if (!lpJniStorage->allocSharedMem(buffSizeInBytes)) {
+            const auto iMem = allocSharedMem(buffSizeInBytes);
+            if (iMem == nullptr) {
                 ALOGE("Error creating AudioTrack in static mode: error creating mem heap base");
                 goto native_init_failure;
             }
@@ -412,19 +432,18 @@
                                   sampleRateInHertz,
                                   format, // word length, PCM
                                   nativeChannelMask, frameCount, AUDIO_OUTPUT_FLAG_NONE,
-                                  audioCallback,
-                                  &(lpJniStorage->mCallbackData), // callback, callback data (user)
+                                  lpJniStorage,
                                   0, // notificationFrames == 0 since not using EVENT_MORE_DATA
                                      // to feed the AudioTrack
-                                  lpJniStorage->mMemBase, // shared mem
+                                  iMem,                   // shared mem
                                   true,                   // thread can call Java
                                   sessionId,              // audio session ID
                                   AudioTrack::TRANSFER_SHARED,
-                                  NULL,       // default offloadInfo
+                                  nullptr ,               // default offloadInfo
                                   AttributionSourceState(), // default uid, pid values
                                   paa.get());
             break;
-
+        }
         default:
             ALOGE("Unknown mode %d", memoryMode);
             goto native_init_failure;
@@ -438,7 +457,7 @@
         // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_JAVA
         lpTrack->setCallerName("java");
     } else {  // end if (nativeAudioTrack == 0)
-        lpTrack = (AudioTrack*)nativeAudioTrack;
+        lpTrack = sp<AudioTrack>::fromExisting(reinterpret_cast<AudioTrack*>(nativeAudioTrack));
         // TODO: We need to find out which members of the Java AudioTrack might
         // need to be initialized from the Native AudioTrack
         // these are directly returned from getters:
@@ -456,15 +475,19 @@
 
         // initialize the callback information:
         // this data will be passed with every AudioTrack callback
-        lpJniStorage = new AudioTrackJniStorage();
+
+        // TODO this callback information is useless, it isn't passed to the
+        // native AudioTrack object
+        /*
         lpJniStorage->mCallbackData.audioTrack_class = (jclass)env->NewGlobalRef(clazz);
         // we use a weak reference so the AudioTrack object can be garbage collected.
         lpJniStorage->mCallbackData.audioTrack_ref = env->NewGlobalRef(weak_this);
         lpJniStorage->mCallbackData.busy = false;
+        */
     }
     lpJniStorage->mAudioTrackCallback =
-            new JNIAudioTrackCallback(env, thiz, lpJniStorage->mCallbackData.audioTrack_ref,
-                                      javaAudioTrackFields.postNativeEventInJava);
+            sp<JNIAudioTrackCallback>::make(env, thiz, lpJniStorage->getAudioTrackWeakRef(),
+                                            javaAudioTrackFields.postNativeEventInJava);
     lpTrack->setAudioTrackCallback(lpJniStorage->mAudioTrackCallback);
 
     nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
@@ -482,17 +505,13 @@
         env->SetIntArrayRegion(jSampleRate, 0, 1, elements);
     }
 
-    {   // scope for the lock
-        Mutex::Autolock l(sLock);
-        sAudioTrackCallBackCookies.add(&lpJniStorage->mCallbackData);
-    }
     // save our newly created C++ AudioTrack in the "nativeTrackInJavaObj" field
     // of the Java object (in mNativeTrackInJavaObj)
-    setAudioTrack(env, thiz, lpTrack);
+    setFieldSp(env, thiz, lpTrack, javaAudioTrackFields.nativeTrackInJavaObj);
 
     // save the JNI resources so we can free them later
     //ALOGV("storing lpJniStorage: %x\n", (long)lpJniStorage);
-    env->SetLongField(thiz, javaAudioTrackFields.jniData, (jlong)lpJniStorage);
+    setFieldSp(env, thiz, lpJniStorage, javaAudioTrackFields.jniData);
 
     // since we had audio attributes, the stream type was derived from them during the
     // creation of the native AudioTrack: push the same value to the Java object
@@ -505,9 +524,6 @@
     if (nSession != NULL) {
         env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
     }
-    env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioTrack_class);
-    env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioTrack_ref);
-    delete lpJniStorage;
     env->SetLongField(thiz, javaAudioTrackFields.jniData, 0);
 
     // lpTrack goes out of scope, so reference count drops to zero
@@ -607,38 +623,9 @@
 
 // ----------------------------------------------------------------------------
 
-#define CALLBACK_COND_WAIT_TIMEOUT_MS 1000
 static void android_media_AudioTrack_release(JNIEnv *env,  jobject thiz) {
-    sp<AudioTrack> lpTrack = setAudioTrack(env, thiz, 0);
-    if (lpTrack == NULL) {
-        return;
-    }
-    //ALOGV("deleting lpTrack: %x\n", (int)lpTrack);
-
-    // delete the JNI data
-    AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetLongField(
-        thiz, javaAudioTrackFields.jniData);
-    // reset the native resources in the Java object so any attempt to access
-    // them after a call to release fails.
-    env->SetLongField(thiz, javaAudioTrackFields.jniData, 0);
-
-    if (pJniStorage) {
-        Mutex::Autolock l(sLock);
-        audiotrack_callback_cookie *lpCookie = &pJniStorage->mCallbackData;
-        //ALOGV("deleting pJniStorage: %x\n", (int)pJniStorage);
-        while (lpCookie->busy) {
-            if (lpCookie->cond.waitRelative(sLock,
-                                            milliseconds(CALLBACK_COND_WAIT_TIMEOUT_MS)) !=
-                                                    NO_ERROR) {
-                break;
-            }
-        }
-        sAudioTrackCallBackCookies.remove(lpCookie);
-        // delete global refs created in native_setup
-        env->DeleteGlobalRef(lpCookie->audioTrack_class);
-        env->DeleteGlobalRef(lpCookie->audioTrack_ref);
-        delete pJniStorage;
-    }
+    setFieldSp(env, thiz, sp<AudioTrack>(nullptr), javaAudioTrackFields.nativeTrackInJavaObj);
+    setFieldSp(env, thiz, sp<AudioTrackJniStorage>(nullptr), javaAudioTrackFields.jniData);
 }
 
 
@@ -1249,17 +1236,18 @@
                 JNIEnv *env,  jobject thiz) {
 
     sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
-    if (lpTrack == NULL) {
+    if (lpTrack == nullptr) {
         return;
     }
-    AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetLongField(
-        thiz, javaAudioTrackFields.jniData);
-    if (pJniStorage == NULL || pJniStorage->mDeviceCallback != 0) {
+    const auto pJniStorage =
+            getFieldSp<AudioTrackJniStorage>(env, thiz, javaAudioTrackFields.jniData);
+    if (pJniStorage == nullptr || pJniStorage->mDeviceCallback != nullptr) {
         return;
     }
+
     pJniStorage->mDeviceCallback =
-    new JNIDeviceCallback(env, thiz, pJniStorage->mCallbackData.audioTrack_ref,
-                          javaAudioTrackFields.postNativeEventInJava);
+            sp<JNIDeviceCallback>::make(env, thiz, pJniStorage->getAudioTrackWeakRef(),
+                                        javaAudioTrackFields.postNativeEventInJava);
     lpTrack->addAudioDeviceCallback(pJniStorage->mDeviceCallback);
 }
 
@@ -1267,12 +1255,13 @@
                 JNIEnv *env,  jobject thiz) {
 
     sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
-    if (lpTrack == NULL) {
+    if (lpTrack == nullptr) {
         return;
     }
-    AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetLongField(
-        thiz, javaAudioTrackFields.jniData);
-    if (pJniStorage == NULL || pJniStorage->mDeviceCallback == 0) {
+    const auto pJniStorage =
+            getFieldSp<AudioTrackJniStorage>(env, thiz, javaAudioTrackFields.jniData);
+
+    if (pJniStorage == nullptr || pJniStorage->mDeviceCallback == nullptr) {
         return;
     }
     lpTrack->removeAudioDeviceCallback(pJniStorage->mDeviceCallback);
diff --git a/core/jni/android_media_AudioTrack.h b/core/jni/android_media_AudioTrack.h
index ef2aa66..d5b858c 100644
--- a/core/jni/android_media_AudioTrack.h
+++ b/core/jni/android_media_AudioTrack.h
@@ -18,15 +18,9 @@
 #define ANDROID_MEDIA_AUDIOTRACK_H
 
 #include "jni.h"
-
+#include <media/AudioTrack.h>
 #include <utils/StrongPointer.h>
 
-namespace android {
-
-class AudioTrack;
-
-}; // namespace android
-
 /* Gets the underlying AudioTrack from an AudioTrack Java object. */
 extern android::sp<android::AudioTrack> android_media_AudioTrack_getAudioTrack(
         JNIEnv* env, jobject audioTrackObj);
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index f76b211..3c2a48a 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -574,6 +574,12 @@
 
     optional SettingProto lte_service_forced = 71 [ (android.privacy).dest = DEST_AUTOMATIC ];
     repeated SettingProto max_error_bytes = 151;
+
+    message ManagedDeviceProvisioning {
+        optional SettingProto managed_provisioning_defer_provisioning_to_role_holder = 1;
+    }
+    optional ManagedDeviceProvisioning managed_device_provisioning = 156;
+
     optional SettingProto mdc_initial_max_retry = 72 [ (android.privacy).dest = DEST_AUTOMATIC ];
 
     message Mhl {
@@ -1077,5 +1083,5 @@
 
     // Please insert fields in alphabetical order and group them into messages
     // if possible (to avoid reaching the method limit).
-    // Next tag = 156;
+    // Next tag = 157;
 }
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5e6d05a..fdb85a9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3663,6 +3663,9 @@
     <!-- Controls whether the navigation bar lets through taps. -->
     <bool name="config_navBarTapThrough">false</bool>
 
+    <!-- Controls whether the IME renders the back and IME switcher buttons or not. -->
+    <bool name="config_imeDrawsImeNavBar">false</bool>
+
     <!-- Controls whether the side edge gestures can always trigger the transient nav bar to
          show. -->
     <bool name="config_navBarAlwaysShowOnSideEdgeGesture">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0190451..db66777 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2996,6 +2996,7 @@
   <java-symbol type="integer" name="config_navBarInteractionMode" />
   <java-symbol type="bool" name="config_navBarCanMove" />
   <java-symbol type="bool" name="config_navBarTapThrough" />
+  <java-symbol type="bool" name="config_imeDrawsImeNavBar" />
   <java-symbol type="bool" name="config_navBarAlwaysShowOnSideEdgeGesture" />
   <java-symbol type="bool" name="config_navBarNeedsScrim" />
   <java-symbol type="bool" name="config_allowSeamlessRotationDespiteNavBarMoving" />
diff --git a/core/tests/coretests/src/android/widget/OWNERS b/core/tests/coretests/src/android/widget/OWNERS
new file mode 100644
index 0000000..5a9aed3
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/OWNERS
@@ -0,0 +1,5 @@
+include /core/java/android/widget/OWNERS
+
+per-file *SuggestionsPopup* = file:/core/java/android/text/OWNERS
+
+per-file *FloatingToolbar*, *SelectionToolbar* = file:/core/java/android/view/textclassifier/OWNERS
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
index 5beaa87..9592376 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
@@ -22,81 +22,101 @@
 
     <!-- The background of the top-level layout acts as the background dim. -->
 
-    <!-- Setting the alpha of the dialog container to 0, since it shouldn't be visible until the
+    <!-- Vertical margin will be set dynamically since it depends on task bounds.
+         Setting the alpha of the dialog container to 0, since it shouldn't be visible until the
          enter animation starts. -->
-    <LinearLayout
+    <FrameLayout
         android:id="@+id/letterbox_education_dialog_container"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:gravity="center_horizontal"
-        android:orientation="vertical"
+        android:layout_marginHorizontal="@dimen/letterbox_education_dialog_margin"
         android:background="@drawable/letterbox_education_dialog_background"
-        android:padding="24dp"
-        android:alpha="0">
+        android:alpha="0"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintWidth_max="@dimen/letterbox_education_dialog_width"
+        app:layout_constrainedHeight="true">
 
-        <ImageView
-            android:id="@+id/letterbox_education_icon"
-            android:layout_width="@dimen/letterbox_education_dialog_icon_size"
-            android:layout_height="@dimen/letterbox_education_dialog_icon_size"
-            android:layout_marginBottom="12dp"
-            android:src="@drawable/letterbox_education_ic_letterboxed_app"/>
-
-        <TextView
-            android:id="@+id/letterbox_education_dialog_title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:maxWidth="@dimen/letterbox_education_dialog_title_max_width"
-            android:lineSpacingExtra="4sp"
-            android:text="@string/letterbox_education_dialog_title"
-            android:textAlignment="center"
-            android:textColor="@color/compat_controls_text"
-            android:textSize="24sp"/>
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="8dp"
-            android:maxWidth="@dimen/letterbox_education_dialog_title_max_width"
-            android:lineSpacingExtra="4sp"
-            android:text="@string/letterbox_education_dialog_subtext"
-            android:textAlignment="center"
-            android:textColor="@color/letterbox_education_text_secondary"
-            android:textSize="14sp"/>
-
-        <LinearLayout
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:gravity="top"
-            android:orientation="horizontal"
-            android:paddingTop="48dp">
-
-            <com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogActionLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                app:icon="@drawable/letterbox_education_ic_screen_rotation"
-                app:text="@string/letterbox_education_screen_rotation_text"/>
-
-            <com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogActionLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginStart="@dimen/letterbox_education_dialog_space_between_actions"
-                app:icon="@drawable/letterbox_education_ic_reposition"
-                app:text="@string/letterbox_education_reposition_text"/>
-
-        </LinearLayout>
-
-        <Button
-            android:id="@+id/letterbox_education_dialog_dismiss_button"
+        <!-- The ScrollView should only wrap the content of the dialog, otherwise the background
+             corner radius will be cut off when scrolling to the top/bottom. -->
+        <ScrollView
             android:layout_width="match_parent"
-            android:layout_height="56dp"
-            android:layout_marginTop="48dp"
-            android:background="@drawable/letterbox_education_dismiss_button_background_ripple"
-            android:text="@string/letterbox_education_got_it"
-            android:textColor="@android:color/system_neutral1_900"
-            android:textAlignment="center"
-            android:contentDescription="@string/letterbox_education_got_it"/>
+            android:layout_height="wrap_content">
 
-    </LinearLayout>
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center_horizontal"
+                android:orientation="vertical"
+                android:padding="24dp">
+
+                <ImageView
+                    android:layout_width="@dimen/letterbox_education_dialog_icon_size"
+                    android:layout_height="@dimen/letterbox_education_dialog_icon_size"
+                    android:layout_marginBottom="12dp"
+                    android:src="@drawable/letterbox_education_ic_letterboxed_app"/>
+
+                <TextView
+                    android:id="@+id/letterbox_education_dialog_title"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:lineSpacingExtra="4sp"
+                    android:text="@string/letterbox_education_dialog_title"
+                    android:textAlignment="center"
+                    android:textColor="@color/compat_controls_text"
+                    android:textSize="24sp"/>
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dp"
+                    android:lineSpacingExtra="4sp"
+                    android:text="@string/letterbox_education_dialog_subtext"
+                    android:textAlignment="center"
+                    android:textColor="@color/letterbox_education_text_secondary"
+                    android:textSize="14sp"/>
+
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:gravity="top"
+                    android:orientation="horizontal"
+                    android:paddingTop="48dp">
+
+                    <com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogActionLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        app:icon="@drawable/letterbox_education_ic_screen_rotation"
+                        app:text="@string/letterbox_education_screen_rotation_text"/>
+
+                    <com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogActionLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart=
+                            "@dimen/letterbox_education_dialog_space_between_actions"
+                        app:icon="@drawable/letterbox_education_ic_reposition"
+                        app:text="@string/letterbox_education_reposition_text"/>
+
+                </LinearLayout>
+
+                <Button
+                    android:id="@+id/letterbox_education_dialog_dismiss_button"
+                    android:layout_width="match_parent"
+                    android:layout_height="56dp"
+                    android:layout_marginTop="48dp"
+                    android:background=
+                        "@drawable/letterbox_education_dismiss_button_background_ripple"
+                    android:text="@string/letterbox_education_got_it"
+                    android:textColor="@android:color/system_neutral1_900"
+                    android:textAlignment="center"
+                    android:contentDescription="@string/letterbox_education_got_it"/>
+
+            </LinearLayout>
+
+        </ScrollView>
+
+    </FrameLayout>
 
 </com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogLayout>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 7a398c5..8a8231d 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -225,15 +225,18 @@
     <!-- The size of an icon in the letterbox education dialog. -->
     <dimen name="letterbox_education_dialog_icon_size">48dp</dimen>
 
+    <!-- The fixed width of the dialog if there is enough space in the parent. -->
+    <dimen name="letterbox_education_dialog_width">472dp</dimen>
+
+    <!-- The margin between the dialog container and its parent. -->
+    <dimen name="letterbox_education_dialog_margin">16dp</dimen>
+
     <!-- The width of each action container in the letterbox education dialog -->
     <dimen name="letterbox_education_dialog_action_width">140dp</dimen>
 
     <!-- The space between two actions in the letterbox education dialog -->
     <dimen name="letterbox_education_dialog_space_between_actions">24dp</dimen>
 
-    <!-- The maximum width of the title and subtitle in the letterbox education dialog. -->
-    <dimen name="letterbox_education_dialog_title_max_width">444dp</dimen>
-
     <!-- The width of the brand image on staring surface. -->
     <dimen name="starting_surface_brand_image_width">200dp</dimen>
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
index 3a37b5e..7c6780a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
@@ -189,15 +189,18 @@
     }
 
     @Override
-    protected void updateSurfacePosition(Rect taskBounds, Rect stableBounds) {
+    @VisibleForTesting
+    public void updateSurfacePosition() {
         if (mLayout == null) {
             return;
         }
         // Position of the button in the container coordinate.
+        final Rect taskBounds = getTaskBounds();
+        final Rect taskStableBounds = getTaskStableBounds();
         final int positionX = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL
-                ? stableBounds.left - taskBounds.left
-                : stableBounds.right - taskBounds.left - mLayout.getMeasuredWidth();
-        final int positionY = stableBounds.bottom - taskBounds.top
+                ? taskStableBounds.left - taskBounds.left
+                : taskStableBounds.right - taskBounds.left - mLayout.getMeasuredWidth();
+        final int positionY = taskStableBounds.bottom - taskBounds.top
                 - mLayout.getMeasuredHeight();
 
         updateSurfacePosition(positionX, positionY);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java
index 7014fcc..5679bc4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java
@@ -51,15 +51,15 @@
  */
 public abstract class CompatUIWindowManagerAbstract extends WindowlessWindowManager {
 
-    protected final SyncTransactionQueue mSyncQueue;
-    protected final int mDisplayId;
     protected final int mTaskId;
-
     protected Context mContext;
-    protected Configuration mTaskConfig;
-    protected ShellTaskOrganizer.TaskListener mTaskListener;
-    protected DisplayLayout mDisplayLayout;
-    protected final Rect mStableBounds;
+
+    private final SyncTransactionQueue mSyncQueue;
+    private final int mDisplayId;
+    private Configuration mTaskConfig;
+    private ShellTaskOrganizer.TaskListener mTaskListener;
+    private DisplayLayout mDisplayLayout;
+    private final Rect mStableBounds;
 
     /**
      * Utility class for adding and releasing a View hierarchy for this {@link
@@ -211,7 +211,7 @@
         boolean layoutDirectionUpdated =
                 mTaskConfig.getLayoutDirection() != prevTaskConfig.getLayoutDirection();
         if (boundsUpdated || layoutDirectionUpdated) {
-            updateSurface();
+            onParentBoundsChanged();
         }
 
         if (layout != null && layoutDirectionUpdated) {
@@ -248,8 +248,9 @@
         displayLayout.getStableBounds(curStableBounds);
         mDisplayLayout = displayLayout;
         if (!prevStableBounds.equals(curStableBounds)) {
-            updateSurface();
+            // mStableBounds should be updated before we call onParentBoundsChanged.
             mStableBounds.set(curStableBounds);
+            onParentBoundsChanged();
         }
     }
 
@@ -289,51 +290,39 @@
     }
 
     /** Re-layouts the view host and updates the surface position. */
-    public void relayout() {
+    void relayout() {
+        relayout(getWindowLayoutParams());
+    }
+
+    protected void relayout(WindowManager.LayoutParams windowLayoutParams) {
         if (mViewHost == null) {
             return;
         }
-        mViewHost.relayout(getWindowLayoutParams());
+        mViewHost.relayout(windowLayoutParams);
         updateSurfacePosition();
     }
 
     /**
-     * Updates the surface following a change in the task bounds, display layout stable bounds,
-     * or the layout direction.
+     * Called following a change in the task bounds, display layout stable bounds, or the layout
+     * direction.
      */
-    protected void updateSurface() {
+    protected void onParentBoundsChanged() {
         updateSurfacePosition();
     }
 
     /**
-     * Updates the position of the surface with respect to the task bounds and display layout
-     * stable bounds.
+     * Updates the position of the surface with respect to the parent bounds.
      */
-    @VisibleForTesting
-    void updateSurfacePosition() {
-        if (mLeash == null) {
-            return;
-        }
-        // Use stable bounds to prevent controls from overlapping with system bars.
-        final Rect taskBounds = mTaskConfig.windowConfiguration.getBounds();
-        final Rect stableBounds = new Rect();
-        mDisplayLayout.getStableBounds(stableBounds);
-        stableBounds.intersect(taskBounds);
-
-        updateSurfacePosition(taskBounds, stableBounds);
-    }
-
-    /**
-     * Updates the position of the surface with respect to the given {@code taskBounds} and {@code
-     * stableBounds}.
-     */
-    protected abstract void updateSurfacePosition(Rect taskBounds, Rect stableBounds);
+    protected abstract void updateSurfacePosition();
 
     /**
      * Updates the position of the surface with respect to the given {@code positionX} and {@code
      * positionY}.
      */
     protected void updateSurfacePosition(int positionX, int positionY) {
+        if (mLeash == null) {
+            return;
+        }
         mSyncQueue.runInSync(t -> {
             if (mLeash == null || !mLeash.isValid()) {
                 Log.w(getTag(), "The leash has been released.");
@@ -347,6 +336,17 @@
         return mContext.getResources().getConfiguration().getLayoutDirection();
     }
 
+    protected Rect getTaskBounds() {
+        return mTaskConfig.windowConfiguration.getBounds();
+    }
+
+    /** Returns the intersection between the task bounds and the display layout stable bounds. */
+    protected Rect getTaskStableBounds() {
+        final Rect result = new Rect(mStableBounds);
+        result.intersect(getTaskBounds());
+        return result;
+    }
+
     @VisibleForTesting
     SurfaceControlViewHost createSurfaceViewHost() {
         return new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduAnimationController.java
index eff2602..3810eca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduAnimationController.java
@@ -43,6 +43,8 @@
 class LetterboxEduAnimationController {
     private static final String TAG = "LetterboxEduAnimation";
 
+    private static final int ENTER_ANIM_START_DELAY_MILLIS = 500;
+
     private final TransitionAnimation mTransitionAnimation;
     private final String mPackageName;
     @AnyRes
@@ -87,6 +89,9 @@
                 mDialogAnimation.getDuration());
         mBackgroundDimAnimator.addListener(getDimAnimatorListener());
 
+        mDialogAnimation.setStartOffset(ENTER_ANIM_START_DELAY_MILLIS);
+        mBackgroundDimAnimator.setStartDelay(ENTER_ANIM_START_DELAY_MILLIS);
+
         dialogContainer.startAnimation(mDialogAnimation);
         mBackgroundDimAnimator.start();
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
index bc1d19b..bb6fe98 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
@@ -20,7 +20,8 @@
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.View;
-import android.widget.FrameLayout;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
 
 import com.android.wm.shell.R;
 
@@ -31,7 +32,7 @@
  * background dim which dismisses the dialog when clicked.
  */
 // TODO(b/215316431): Add tests
-class LetterboxEduDialogLayout extends FrameLayout {
+class LetterboxEduDialogLayout extends ConstraintLayout {
 
     // The alpha of a background is a number between 0 (fully transparent) to 255 (fully opaque).
     // 204 is simply 255 * 0.8.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
index 074610b..bb4d427 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
@@ -26,6 +26,7 @@
 import android.provider.Settings;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup.MarginLayoutParams;
 import android.view.WindowManager;
 
 import com.android.wm.shell.R;
@@ -109,6 +110,7 @@
     protected View createLayout() {
         setSeenLetterboxEducation();
         mLayout = inflateLayout();
+        updateDialogMargins();
 
         mAnimationController.startEnterAnimation(mLayout, /* endCallback= */
                 this::setDismissOnClickListener);
@@ -116,6 +118,22 @@
         return mLayout;
     }
 
+    private void updateDialogMargins() {
+        if (mLayout == null) {
+            return;
+        }
+        final View dialogContainer = mLayout.getDialogContainer();
+        MarginLayoutParams marginParams = (MarginLayoutParams) dialogContainer.getLayoutParams();
+        int verticalMargin = (int) mContext.getResources().getDimension(
+                R.dimen.letterbox_education_dialog_margin);
+
+        final Rect taskBounds = getTaskBounds();
+        final Rect taskStableBounds = getTaskStableBounds();
+        marginParams.topMargin = taskStableBounds.top - taskBounds.top + verticalMargin;
+        marginParams.bottomMargin = taskBounds.bottom - taskStableBounds.bottom + verticalMargin;
+        dialogContainer.setLayoutParams(marginParams);
+    }
+
     private LetterboxEduDialogLayout inflateLayout() {
         return (LetterboxEduDialogLayout) LayoutInflater.from(mContext).inflate(
                 R.layout.letterbox_education_dialog_layout, null);
@@ -150,20 +168,26 @@
     }
 
     @Override
-    protected void updateSurface() {
-        // We need to relayout because the layout dimensions depend on the task bounds.
-        relayout();
+    protected void onParentBoundsChanged() {
+        if (mLayout == null) {
+            return;
+        }
+        // Both the layout dimensions and dialog margins depend on the parent bounds.
+        WindowManager.LayoutParams windowLayoutParams = getWindowLayoutParams();
+        mLayout.setLayoutParams(windowLayoutParams);
+        updateDialogMargins();
+        relayout(windowLayoutParams);
     }
 
     @Override
-    protected void updateSurfacePosition(Rect taskBounds, Rect stableBounds) {
+    protected void updateSurfacePosition() {
         // Nothing to do, since the position of the surface is fixed to the top left corner (0,0)
         // of the task (parent surface), which is the default position of a surface.
     }
 
     @Override
     protected WindowManager.LayoutParams getWindowLayoutParams() {
-        final Rect taskBounds = mTaskConfig.windowConfiguration.getBounds();
+        final Rect taskBounds = getTaskBounds();
         return getWindowLayoutParams(/* width= */ taskBounds.width(), /* height= */
                 taskBounds.height());
     }
diff --git a/libs/androidfw/tests/BackupHelpers_test.cpp b/libs/androidfw/tests/BackupHelpers_test.cpp
index 86b7fb3..c2fcb69 100644
--- a/libs/androidfw/tests/BackupHelpers_test.cpp
+++ b/libs/androidfw/tests/BackupHelpers_test.cpp
@@ -50,7 +50,7 @@
 TEST_F(BackupHelpersTest, WriteTarFileWithSizeGreaterThan2GB) {
   TemporaryFile tf;
   // Allocate a 2 GB file.
-  off64_t fileSize = 2ll * 1024ll * 1024ll * 1024ll + 512ll;
+  off64_t fileSize = 2LL * 1024LL * 1024LL * 1024LL + 512LL;
   ASSERT_EQ(0, posix_fallocate64(tf.fd, 0, fileSize));
   off64_t tarSize = 0;
   int err = write_tarfile(/* packageName */ String8("test-pkg"), /* domain */ String8(""), /* rootpath */ String8(""), /* filePath */ String8(tf.path), /* outSize */ &tarSize, /* writer */ NULL);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 7381e05..a2b6992 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -696,6 +696,14 @@
                 Settings.Global.MAX_ERROR_BYTES_PREFIX,
                 GlobalSettingsProto.MAX_ERROR_BYTES);
 
+        final long managedDeviceProvisioningToken =
+                p.start(GlobalSettingsProto.MANAGED_DEVICE_PROVISIONING);
+        dumpSetting(s, p,
+                Settings.Global.MANAGED_PROVISIONING_DEFER_PROVISIONING_TO_ROLE_HOLDER,
+                GlobalSettingsProto.ManagedDeviceProvisioning
+                        .MANAGED_PROVISIONING_DEFER_PROVISIONING_TO_ROLE_HOLDER);
+        p.end(managedDeviceProvisioningToken);
+
         final long euiccToken = p.start(GlobalSettingsProto.EUICC);
         dumpSetting(s, p,
                 Settings.Global.EUICC_PROVISIONED,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 2905429..3f4372b 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -594,6 +594,7 @@
                     Settings.Global.KEY_CHORD_POWER_VOLUME_UP,
                     Settings.Global.CLOCKWORK_HOME_READY,
                     Settings.Global.WATCHDOG_TIMEOUT_MILLIS,
+                    Settings.Global.MANAGED_PROVISIONING_DEFER_PROVISIONING_TO_ROLE_HOLDER,
                     Settings.Global.Wearable.BATTERY_SAVER_MODE,
                     Settings.Global.Wearable.COMBINED_LOCATION_ENABLED,
                     Settings.Global.Wearable.HAS_PAY_TOKENS,
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index ffee894..d4b4a74 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -20,7 +20,7 @@
 import android.app.smartspace.SmartspaceAction;
 import android.app.smartspace.SmartspaceTarget;
 import android.app.smartspace.SmartspaceTargetEvent;
-import android.app.smartspace.uitemplatedata.SmartspaceTapAction;
+import android.app.smartspace.uitemplatedata.TapAction;
 import android.content.ActivityNotFoundException;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
@@ -144,7 +144,7 @@
             }
         }
 
-        default void startFromAction(SmartspaceTapAction action, View v, boolean showOnLockscreen) {
+        default void startFromAction(TapAction action, View v, boolean showOnLockscreen) {
             try {
                 if (action.getIntent() != null) {
                     startIntent(v, action.getIntent(), showOnLockscreen);
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 6352f81..cf69512 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -1,22 +1,16 @@
 # Preserve line number information for debugging stack traces.
 -keepattributes SourceFile,LineNumberTable
 
--keep class com.android.systemui.recents.OverviewProxyRecentsImpl
--keep class com.android.systemui.statusbar.car.CarStatusBar
--keep class com.android.systemui.statusbar.phone.StatusBar
--keep class com.android.systemui.statusbar.tv.TvStatusBar
 -keep class com.android.systemui.car.CarSystemUIFactory
 -keep class com.android.systemui.SystemUIFactory
 -keep class com.android.systemui.tv.TvSystemUIFactory
--keep class * extends com.android.systemui.CoreStartable
--keep class * implements com.android.systemui.CoreStartable$Injector
 
 -keepclasseswithmembers class * {
     public <init>(android.content.Context, android.util.AttributeSet);
 }
 
 -keep class ** extends androidx.preference.PreferenceFragment
--keep class com.android.systemui.tuner.*
+
 -keep class com.android.systemui.plugins.** {
     *;
 }
@@ -25,10 +19,6 @@
 }
 -keep class androidx.core.app.CoreComponentFactory
 
--keep public class * extends com.android.systemui.CoreStartable {
-    public <init>(android.content.Context);
-}
-
 # Keep the wm shell lib
 -keep class com.android.wm.shell.*
 # Keep the protolog group methods that are called by the generated code
@@ -36,11 +26,6 @@
     *;
 }
 
--keep,allowoptimization,allowaccessmodification class com.android.systemui.dagger.GlobalRootComponent { !synthetic *; }
--keep,allowoptimization,allowaccessmodification class com.android.systemui.dagger.GlobalRootComponent$SysUIComponentImpl { !synthetic *; }
--keep,allowoptimization,allowaccessmodification class com.android.systemui.dagger.Dagger** { !synthetic *; }
--keep,allowoptimization,allowaccessmodification class com.android.systemui.tv.Dagger** { !synthetic *; }
-
 # Allows proguard to make private and protected methods and fields public as
 # part of optimization. This lets proguard inline trivial getter/setter methods.
 -allowaccessmodification
diff --git a/packages/SystemUI/res-keyguard/layout/footer_actions.xml b/packages/SystemUI/res-keyguard/layout/footer_actions.xml
index 339cab4..fb401ee 100644
--- a/packages/SystemUI/res-keyguard/layout/footer_actions.xml
+++ b/packages/SystemUI/res-keyguard/layout/footer_actions.xml
@@ -77,16 +77,6 @@
             android:src="@drawable/ic_settings"
             android:tint="?android:attr/textColorPrimary" />
 
-        <com.android.systemui.statusbar.AlphaOptimizedImageView
-            android:id="@+id/tuner_icon"
-            android:layout_width="8dp"
-            android:layout_height="8dp"
-            android:layout_gravity="center_horizontal|bottom"
-            android:layout_marginBottom="@dimen/qs_footer_icon_padding"
-            android:src="@drawable/tuner"
-            android:tint="?android:attr/textColorTertiary"
-            android:visibility="invisible" />
-
     </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
 
 </com.android.systemui.qs.FooterActionsView>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/layout/new_footer_actions.xml b/packages/SystemUI/res-keyguard/layout/new_footer_actions.xml
index 4884df7..59712c0 100644
--- a/packages/SystemUI/res-keyguard/layout/new_footer_actions.xml
+++ b/packages/SystemUI/res-keyguard/layout/new_footer_actions.xml
@@ -78,16 +78,6 @@
                 android:src="@drawable/ic_settings"
                 android:tint="?android:attr/textColorPrimary" />
 
-            <com.android.systemui.statusbar.AlphaOptimizedImageView
-                android:id="@+id/tuner_icon"
-                android:layout_width="8dp"
-                android:layout_height="8dp"
-                android:layout_gravity="center_horizontal|bottom"
-                android:layout_marginBottom="@dimen/qs_footer_icon_padding"
-                android:src="@drawable/tuner"
-                android:tint="?android:attr/textColorTertiary"
-                android:visibility="invisible" />
-
         </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
 
         <com.android.systemui.statusbar.AlphaOptimizedImageView
diff --git a/packages/SystemUI/res/layout/dream_overlay_complication_clock_time.xml b/packages/SystemUI/res/layout/dream_overlay_complication_clock_time.xml
index 4824f4c..e066d38 100644
--- a/packages/SystemUI/res/layout/dream_overlay_complication_clock_time.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_complication_clock_time.xml
@@ -20,6 +20,7 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:fontFamily="@font/clock"
+    android:includeFontPadding="false"
     android:textColor="@android:color/white"
     android:format12Hour="h:mm"
     android:format24Hour="kk:mm"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 99e0ec1..37f4564 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2027,6 +2027,7 @@
         mAuthController.addCallback(new AuthController.Callback() {
             @Override
             public void onAllAuthenticatorsRegistered() {
+                mainExecutor.execute(() -> updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE));
             }
 
             @Override
@@ -2156,6 +2157,10 @@
             return;
         }
 
+        // don't start running fingerprint until they're registered
+        if (!mAuthController.areAllAuthenticatorsRegistered()) {
+            return;
+        }
         final boolean shouldListenForFingerprint = shouldListenForFingerprint(isUdfpsSupported());
         final boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING
                 || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING;
@@ -3523,6 +3528,8 @@
             final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
             BiometricAuthenticated fingerprint = mUserFingerprintAuthenticated.get(userId);
             pw.println("  Fingerprint state (user=" + userId + ")");
+            pw.println("    areAllAuthenticatorsRegistered="
+                    + mAuthController.areAllAuthenticatorsRegistered());
             pw.println("    allowed="
                     + (fingerprint != null
                             && isUnlockingWithBiometricAllowed(fingerprint.mIsStrongBiometric)));
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index fe5e36e..dfb8c18 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -136,6 +136,7 @@
     @NonNull private final SparseBooleanArray mUdfpsEnrolledForUser;
     @NonNull private final SensorPrivacyManager mSensorPrivacyManager;
     private final WakefulnessLifecycle mWakefulnessLifecycle;
+    private boolean mAllAuthenticatorsRegistered;
 
     private class BiometricTaskStackListener extends TaskStackListener {
         @Override
@@ -226,6 +227,13 @@
         }
     }
 
+    /**
+     * Whether all authentictors have been registered.
+     */
+    public boolean areAllAuthenticatorsRegistered() {
+        return mAllAuthenticatorsRegistered;
+    }
+
     private void handleAllAuthenticatorsRegistered(
             List<FingerprintSensorPropertiesInternal> sensors) {
         mExecution.assertIsMainThread();
@@ -233,6 +241,7 @@
             Log.d(TAG, "handleAllAuthenticatorsRegistered | sensors: " + Arrays.toString(
                     sensors.toArray()));
         }
+        mAllAuthenticatorsRegistered = true;
         mFpProps = sensors;
         List<FingerprintSensorPropertiesInternal> udfpsProps = new ArrayList<>();
         List<FingerprintSensorPropertiesInternal> sidefpsProps = new ArrayList<>();
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index 6145f0f..eee3955 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -28,6 +28,7 @@
 import android.view.ViewGroup
 import android.view.ViewGroupOverlay
 import androidx.annotation.VisibleForTesting
+import com.android.keyguard.KeyguardViewController
 import com.android.systemui.R
 import com.android.systemui.animation.Interpolators
 import com.android.systemui.dagger.SysUISingleton
@@ -40,7 +41,6 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator
 import com.android.systemui.statusbar.phone.KeyguardBypassController
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.Utils
@@ -83,7 +83,7 @@
     private val notifLockscreenUserManager: NotificationLockscreenUserManager,
     configurationController: ConfigurationController,
     wakefulnessLifecycle: WakefulnessLifecycle,
-    private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
+    private val keyguardViewController: KeyguardViewController,
     private val dreamOverlayStateController: DreamOverlayStateController
 ) {
 
@@ -1016,7 +1016,7 @@
 
     private fun isLockScreenVisibleToUser(): Boolean {
         return !statusBarStateController.isDozing &&
-                !statusBarKeyguardViewManager.isBouncerShowing &&
+                !keyguardViewController.isBouncerShowing &&
                 statusBarStateController.state == StatusBarState.KEYGUARD &&
                 notifLockscreenUserManager.shouldShowLockscreenNotifications() &&
                 statusBarStateController.isExpanded &&
@@ -1025,7 +1025,7 @@
 
     private fun isLockScreenShadeVisibleToUser(): Boolean {
         return !statusBarStateController.isDozing &&
-                !statusBarKeyguardViewManager.isBouncerShowing &&
+                !keyguardViewController.isBouncerShowing &&
                 (statusBarStateController.state == StatusBarState.SHADE_LOCKED ||
                         (statusBarStateController.state == StatusBarState.KEYGUARD && qsExpanded))
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
index 5df8b80..a262b8a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
@@ -24,7 +24,6 @@
 import android.view.View
 import android.view.ViewGroup
 import android.widget.LinearLayout
-import android.widget.Toast
 import androidx.annotation.VisibleForTesting
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.MetricsLogger
@@ -46,7 +45,6 @@
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.statusbar.policy.UserInfoController
 import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener
-import com.android.systemui.tuner.TunerService
 import com.android.systemui.util.DualHeightHorizontalLinearLayout
 import com.android.systemui.util.ViewController
 import com.android.systemui.util.settings.GlobalSettings
@@ -71,7 +69,6 @@
     private val fgsManagerFooterController: QSFgsManagerFooter,
     private val falsingManager: FalsingManager,
     private val metricsLogger: MetricsLogger,
-    private val tunerService: TunerService,
     private val globalActionsDialog: GlobalActionsDialogLite,
     private val uiEventLogger: UiEventLogger,
     @Named(PM_LITE_ENABLED) private val showPMLiteButton: Boolean,
@@ -131,22 +128,7 @@
                 return@OnClickListener
             }
             metricsLogger.action(MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH)
-            if (settingsButton.isTunerClick) {
-                activityStarter.postQSRunnableDismissingKeyguard {
-                    if (isTunerEnabled()) {
-                        tunerService.showResetRequest {
-                            // Relaunch settings so that the tuner disappears.
-                            startSettingsActivity()
-                        }
-                    } else {
-                        Toast.makeText(context, R.string.tuner_toast, Toast.LENGTH_LONG).show()
-                        tunerService.isTunerEnabled = true
-                    }
-                    startSettingsActivity()
-                }
-            } else {
-                startSettingsActivity()
-            }
+            startSettingsActivity()
         } else if (v === powerMenuLite) {
             uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
             globalActionsDialog.showOrHideDialog(false, true, v)
@@ -228,7 +210,7 @@
     }
 
     private fun updateView() {
-        mView.updateEverything(isTunerEnabled(), multiUserSwitchController.isMultiUserEnabled)
+        mView.updateEverything(multiUserSwitchController.isMultiUserEnabled)
     }
 
     override fun onViewDetached() {
@@ -254,7 +236,7 @@
     }
 
     fun disable(state2: Int) {
-        mView.disable(state2, isTunerEnabled(), multiUserSwitchController.isMultiUserEnabled)
+        mView.disable(state2, multiUserSwitchController.isMultiUserEnabled)
     }
 
     fun setExpansion(headerExpansionFraction: Float) {
@@ -275,6 +257,4 @@
     fun setKeyguardShowing(showing: Boolean) {
         setExpansion(lastExpansion)
     }
-
-    private fun isTunerEnabled() = tunerService.isTunerEnabled
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
index 18e0cfa..9413a90 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
@@ -17,7 +17,6 @@
 
 import android.app.StatusBarManager
 import android.content.Context
-import android.content.res.Configuration
 import android.graphics.PorterDuff
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.RippleDrawable
@@ -42,7 +41,6 @@
     private lateinit var settingsButton: SettingsButton
     private lateinit var multiUserSwitch: MultiUserSwitch
     private lateinit var multiUserAvatar: ImageView
-    private lateinit var tunerIcon: View
 
     private var qsDisabled = false
     private var expansionAmount = 0f
@@ -53,50 +51,30 @@
         settingsContainer = findViewById(R.id.settings_button_container)
         multiUserSwitch = findViewById(R.id.multi_user_switch)
         multiUserAvatar = multiUserSwitch.findViewById(R.id.multi_user_avatar)
-        tunerIcon = requireViewById(R.id.tuner_icon)
 
         // RenderThread is doing more harm than good when touching the header (to expand quick
         // settings), so disable it for this view
         if (settingsButton.background is RippleDrawable) {
             (settingsButton.background as RippleDrawable).setForceSoftware(true)
         }
-        updateResources()
         importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES
     }
 
-    override fun onConfigurationChanged(newConfig: Configuration) {
-        super.onConfigurationChanged(newConfig)
-        updateResources()
-    }
-
-    override fun onRtlPropertiesChanged(layoutDirection: Int) {
-        super.onRtlPropertiesChanged(layoutDirection)
-        updateResources()
-    }
-
-    private fun updateResources() {
-        val tunerIconTranslation = mContext.resources
-                .getDimensionPixelOffset(R.dimen.qs_footer_tuner_icon_translation).toFloat()
-        tunerIcon.translationX = if (isLayoutRtl) (-tunerIconTranslation) else tunerIconTranslation
-    }
-
     fun disable(
         state2: Int,
-        isTunerEnabled: Boolean,
         multiUserEnabled: Boolean
     ) {
         val disabled = state2 and StatusBarManager.DISABLE2_QUICK_SETTINGS != 0
         if (disabled == qsDisabled) return
         qsDisabled = disabled
-        updateEverything(isTunerEnabled, multiUserEnabled)
+        updateEverything(multiUserEnabled)
     }
 
     fun updateEverything(
-        isTunerEnabled: Boolean,
         multiUserEnabled: Boolean
     ) {
         post {
-            updateVisibilities(isTunerEnabled, multiUserEnabled)
+            updateVisibilities(multiUserEnabled)
             updateClickabilities()
             isClickable = false
         }
@@ -108,11 +86,9 @@
     }
 
     private fun updateVisibilities(
-        isTunerEnabled: Boolean,
         multiUserEnabled: Boolean
     ) {
         settingsContainer.visibility = if (qsDisabled) GONE else VISIBLE
-        tunerIcon.visibility = if (isTunerEnabled) VISIBLE else INVISIBLE
         multiUserSwitch.visibility = if (multiUserEnabled) VISIBLE else GONE
         val isDemo = UserManager.isDeviceInDemoMode(context)
         settingsButton.visibility = if (isDemo) INVISIBLE else VISIBLE
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index d610b37..b141110 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -309,7 +309,12 @@
      * delayed for a few seconds. This might be useful to play animations without reducing FPS.
      */
     public boolean shouldDelayDisplayDozeTransition() {
-        return mScreenOffAnimationController.shouldDelayDisplayDozeTransition();
+        return willAnimateFromLockScreenToAod()
+                || mScreenOffAnimationController.shouldDelayDisplayDozeTransition();
+    }
+
+    private boolean willAnimateFromLockScreenToAod() {
+        return getAlwaysOn() && mKeyguardShowing;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index d97815f..b23d870 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -34,6 +34,8 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
+import androidx.annotation.WorkerThread;
+
 import com.android.internal.util.ArrayUtils;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.R;
@@ -287,6 +289,7 @@
     }
 
     @Override
+    @WorkerThread
     public boolean isTunerEnabled() {
         return mUserTracker.getUserContext().getPackageManager().getComponentEnabledSetting(
                 mTunerComponent) == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index f71dd24..42e15c4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -243,6 +243,9 @@
         verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
         mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
         mKeyguardUpdateMonitor.registerCallback(mTestCallback);
+
+        mTestableLooper.processAllMessages();
+        when(mAuthController.areAllAuthenticatorsRegistered()).thenReturn(true);
     }
 
     @After
@@ -471,6 +474,18 @@
     }
 
     @Test
+    public void test_doesNotTryToAuthenticateFingerprint_whenAuthenticatorsNotRegistered() {
+        when(mAuthController.areAllAuthenticatorsRegistered()).thenReturn(false);
+
+        mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
+        mTestableLooper.processAllMessages();
+
+        verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+                anyInt(), anyInt());
+        verify(mFingerprintManager, never()).detectFingerprint(any(), any(), anyInt());
+    }
+
+    @Test
     public void testFingerprintDoesNotAuth_whenEncrypted() {
         testFingerprintWhenStrongAuth(
                 STRONG_AUTH_REQUIRED_AFTER_BOOT);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
index 97b3b10..e606be1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
@@ -22,6 +22,7 @@
 import android.view.ViewGroup
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardViewController
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq
@@ -32,7 +33,6 @@
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.SysuiStatusBarStateController
 import com.android.systemui.statusbar.phone.KeyguardBypassController
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.animation.UniqueObjectHostView
@@ -81,7 +81,7 @@
     @Mock
     private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
     @Mock
-    private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
+    private lateinit var keyguardViewController: KeyguardViewController
     @Mock
     private lateinit var configurationController: ConfigurationController
     @Mock
@@ -113,7 +113,7 @@
                 notificationLockscreenUserManager,
                 configurationController,
                 wakefulnessLifecycle,
-                statusBarKeyguardViewManager,
+                keyguardViewController,
                 dreamOverlayStateController)
         verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture())
         verify(statusBarStateController).addCallback(statusBarCallback.capture())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
index 91a9f9e..8ce50a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
@@ -12,7 +12,6 @@
 import com.android.internal.logging.MetricsLogger
 import com.android.internal.logging.UiEventLogger
 import com.android.internal.logging.testing.FakeMetricsLogger
-import com.android.systemui.Dependency
 import com.android.systemui.R
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.flags.FeatureFlags
@@ -23,9 +22,7 @@
 import com.android.systemui.statusbar.phone.MultiUserSwitchController
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.statusbar.policy.UserInfoController
-import com.android.systemui.tuner.TunerService
 import com.android.systemui.util.settings.FakeSettings
-import com.android.systemui.utils.leaks.FakeTunerService
 import com.android.systemui.utils.leaks.LeakCheckedTest
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
@@ -82,8 +79,6 @@
         MockitoAnnotations.initMocks(this)
         testableLooper = TestableLooper.get(this)
         fakeSettings = FakeSettings()
-        injectLeakCheckedDependencies(*LeakCheckedTest.ALL_SUPPORTED_CLASSES)
-        val fakeTunerService = Dependency.get(TunerService::class.java) as FakeTunerService
 
         whenever(multiUserSwitchControllerFactory.create(any()))
                 .thenReturn(multiUserSwitchController)
@@ -95,9 +90,8 @@
         controller = FooterActionsController(view, multiUserSwitchControllerFactory,
                 activityStarter, userManager, userTracker, userInfoController,
                 deviceProvisionedController, securityFooterController, fgsManagerController,
-                falsingManager, metricsLogger, fakeTunerService,
-                globalActionsDialog, uiEventLogger, showPMLiteButton = true, fakeSettings,
-                Handler(testableLooper.looper), featureFlags)
+                falsingManager, metricsLogger, globalActionsDialog, uiEventLogger,
+                showPMLiteButton = true, fakeSettings, Handler(testableLooper.looper), featureFlags)
         controller.init()
         ViewUtils.attachView(view)
         // View looper is the testable looper associated with the test
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
index cd53227..66fc2ae 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
@@ -30,6 +30,9 @@
     <!-- Controls whether the navigation bar lets through taps. -->
     <bool name="config_navBarTapThrough">true</bool>
 
+    <!-- Controls whether the IME renders the back and IME switcher buttons or not. -->
+    <bool name="config_imeDrawsImeNavBar">true</bool>
+
     <!-- Controls the size of the back gesture inset. -->
     <dimen name="config_backGestureInset">30dp</dimen>
 
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
index 88cb74d79..120a489 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
@@ -30,6 +30,9 @@
     <!-- Controls whether the navigation bar lets through taps. -->
     <bool name="config_navBarTapThrough">true</bool>
 
+    <!-- Controls whether the IME renders the back and IME switcher buttons or not. -->
+    <bool name="config_imeDrawsImeNavBar">true</bool>
+
     <!-- Controls the size of the back gesture inset. -->
     <dimen name="config_backGestureInset">40dp</dimen>
 
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
index 70c41d0..c18d892 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
@@ -30,6 +30,9 @@
     <!-- Controls whether the navigation bar lets through taps. -->
     <bool name="config_navBarTapThrough">true</bool>
 
+    <!-- Controls whether the IME renders the back and IME switcher buttons or not. -->
+    <bool name="config_imeDrawsImeNavBar">true</bool>
+
     <!-- Controls the size of the back gesture inset. -->
     <dimen name="config_backGestureInset">18dp</dimen>
 
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
index de26394..877b5f8 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
@@ -30,6 +30,9 @@
     <!-- Controls whether the navigation bar lets through taps. -->
     <bool name="config_navBarTapThrough">true</bool>
 
+    <!-- Controls whether the IME renders the back and IME switcher buttons or not. -->
+    <bool name="config_imeDrawsImeNavBar">true</bool>
+
     <!-- Controls the size of the back gesture inset. -->
     <dimen name="config_backGestureInset">32dp</dimen>
 
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index 6c220f6..52a0aa7 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -261,7 +261,6 @@
                                 pw.println("");
                             }
                         } catch (PackageManager.NameNotFoundException e) {
-                            pw.println(packageName);
                             pw.println(packageName
                                     + ";ERROR:Unable to find PackageInfo for this module.");
                             if (verbose) {
diff --git a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
index dc4d04f..bdc5711 100644
--- a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
+++ b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
@@ -70,11 +70,15 @@
             "validate_notification_people_enabled";
     private static final String[] LOOKUP_PROJECTION = { Contacts._ID, Contacts.LOOKUP_KEY,
             Contacts.STARRED, Contacts.HAS_PHONE_NUMBER };
-    private static final String[] PHONE_LOOKUP_PROJECTION =
-            { ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER };
     private static final int MAX_PEOPLE = 10;
     private static final int PEOPLE_CACHE_SIZE = 200;
 
+    /** Columns used to look up phone numbers for contacts. */
+    @VisibleForTesting
+    static final String[] PHONE_LOOKUP_PROJECTION =
+            { ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER,
+                    ContactsContract.CommonDataKinds.Phone.NUMBER };
+
     /** Indicates that the notification does not reference any valid contacts. */
     static final float NONE = 0f;
 
@@ -548,14 +552,21 @@
             return mPhoneLookupKey;
         }
 
-        // Merge phone number found in this lookup and store it in mPhoneNumbers.
+        // Merge phone numbers found in this lookup and store them in mPhoneNumbers.
         public void mergePhoneNumber(Cursor cursor) {
-            final int phoneNumIdx = cursor.getColumnIndex(
+            final int normalizedNumIdx = cursor.getColumnIndex(
                     ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER);
-            if (phoneNumIdx >= 0) {
-                mPhoneNumbers.add(cursor.getString(phoneNumIdx));
+            if (normalizedNumIdx >= 0) {
+                mPhoneNumbers.add(cursor.getString(normalizedNumIdx));
             } else {
-                if (DEBUG) Slog.d(TAG, "invalid cursor: no NORMALIZED_NUMBER");
+                if (DEBUG) Slog.d(TAG, "cursor data not found: no NORMALIZED_NUMBER");
+            }
+
+            final int numIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
+            if (numIdx >= 0) {
+                mPhoneNumbers.add(cursor.getString(numIdx));
+            } else {
+                if (DEBUG) Slog.d(TAG, "cursor data not found: no NUMBER");
             }
         }
 
diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java
index d04b331..2a6dd84 100644
--- a/services/core/java/com/android/server/notification/ZenModeFiltering.java
+++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java
@@ -40,8 +40,6 @@
 import com.android.internal.util.NotificationMessagingUtil;
 
 import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
 import java.util.Date;
 
 public class ZenModeFiltering {
@@ -416,16 +414,10 @@
                 if (person == null) continue;
                 final Uri uri = Uri.parse(person);
                 if ("tel".equals(uri.getScheme())) {
-                    String tel = uri.getSchemeSpecificPart();
-                    // while ideally we should not need to do this, sometimes we have seen tel
-                    // numbers given in a url-encoded format
-                    try {
-                        tel = URLDecoder.decode(tel, "UTF-8");
-                    } catch (UnsupportedEncodingException e) {
-                        // ignore, keep the original tel string
-                        Slog.w(TAG, "unsupported encoding in tel: uri input");
-                    }
-                    mTelCalls.put(tel, now);
+                    // while ideally we should not need to decode this, sometimes we have seen tel
+                    // numbers given in an encoded format
+                    String tel = Uri.decode(uri.getSchemeSpecificPart());
+                    if (tel != null) mTelCalls.put(tel, now);
                 } else {
                     // for non-tel calls, store the entire string, uri-component and all
                     mOtherCalls.put(person, now);
@@ -436,7 +428,7 @@
             // provided; these are in the format of just a phone number string
             if (phoneNumbers != null) {
                 for (String num : phoneNumbers) {
-                    mTelCalls.put(num, now);
+                    if (num != null) mTelCalls.put(num, now);
                 }
             }
         }
@@ -456,17 +448,13 @@
                         return true;
                     } else {
                         // see if a number that matches via areSameNumber exists
-                        String numberToCheck = number;
-                        try {
-                            numberToCheck = URLDecoder.decode(number, "UTF-8");
-                        } catch (UnsupportedEncodingException e) {
-                            // ignore, continue to use the original string
-                            Slog.w(TAG, "unsupported encoding in tel: uri input");
-                        }
-                        for (String prev : mTelCalls.keySet()) {
-                            if (PhoneNumberUtils.areSamePhoneNumber(
-                                    numberToCheck, prev, defaultCountryCode)) {
-                                return true;
+                        String numberToCheck = Uri.decode(number);
+                        if (numberToCheck != null) {
+                            for (String prev : mTelCalls.keySet()) {
+                                if (PhoneNumberUtils.areSamePhoneNumber(
+                                        numberToCheck, prev, defaultCountryCode)) {
+                                    return true;
+                                }
                             }
                         }
                     }
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index 4f1a9e7..d117967 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -1382,7 +1382,7 @@
                 }
             } else {
                 callingPkgSetting = null;
-                callingSharedPkgSettings = ((SharedUserSetting) callingSetting).packages;
+                callingSharedPkgSettings = ((SharedUserSetting) callingSetting).getPackageStates();
             }
             if (DEBUG_TRACING) {
                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 04f0aab..c437697 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -2176,11 +2176,13 @@
                 return null;
             }
             final SharedUserSetting sus = (SharedUserSetting) obj;
-            final int n = sus.packages.size();
+            final ArraySet<PackageStateInternal> packageStates =
+                    (ArraySet<PackageStateInternal>) sus.getPackageStates();
+            final int n = packageStates.size();
             String[] res = new String[n];
             int i = 0;
             for (int index = 0; index < n; index++) {
-                final PackageStateInternal ps = sus.packages.valueAt(index);
+                final PackageStateInternal ps = packageStates.valueAt(index);
                 if (ps.getUserStateOrDefault(userId).isInstalled()
                         && !shouldFilterApplication(ps, callingUid, userId)) {
                     res[i++] = ps.getPackageName();
@@ -2710,8 +2712,10 @@
     public final boolean shouldFilterApplication(@NonNull SharedUserSetting sus,
             int callingUid, int userId) {
         boolean filterApp = true;
-        for (int index = sus.packages.size() - 1; index >= 0 && filterApp; index--) {
-            filterApp &= shouldFilterApplication(sus.packages.valueAt(index),
+        final ArraySet<PackageStateInternal> packageStates =
+                (ArraySet<PackageStateInternal>) sus.getPackageStates();
+        for (int index = packageStates.size() - 1; index >= 0 && filterApp; index--) {
+            filterApp &= shouldFilterApplication(packageStates.valueAt(index),
                     callingUid, /* component */ null, TYPE_UNKNOWN, userId);
         }
         return filterApp;
@@ -4468,9 +4472,11 @@
         final Object obj = mSettings.getSettingBase(appId);
         if (obj instanceof SharedUserSetting) {
             final SharedUserSetting sus = (SharedUserSetting) obj;
-            final int numPackages = sus.packages.size();
+            final ArraySet<PackageStateInternal> packageStates =
+                    (ArraySet<PackageStateInternal>) sus.getPackageStates();
+            final int numPackages = packageStates.size();
             for (int index = 0; index < numPackages; index++) {
-                final PackageSetting ps = sus.packages.valueAt(index);
+                final PackageStateInternal ps = packageStates.valueAt(index);
                 if (ps.isPrivileged()) {
                     return true;
                 }
@@ -5290,8 +5296,9 @@
             final AndroidPackage pkg = ((PackageSetting) setting).getPkg();
             return pkg != null && mAppsFilter.canQueryPackage(pkg, targetPackageName);
         } else {
-            final ArraySet<PackageSetting> callingSharedPkgSettings =
-                    ((SharedUserSetting) setting).packages;
+            final ArraySet<PackageStateInternal> callingSharedPkgSettings =
+                    (ArraySet<PackageStateInternal>)
+                            ((SharedUserSetting) setting).getPackageStates();
             for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
                 final AndroidPackage pkg = callingSharedPkgSettings.valueAt(i).getPkg();
                 if (pkg != null && mAppsFilter.canQueryPackage(pkg, targetPackageName)) {
@@ -5595,10 +5602,12 @@
         final SettingBase settingBase = mSettings.getSettingBase(appId);
         if (settingBase instanceof SharedUserSetting) {
             final SharedUserSetting sus = (SharedUserSetting) settingBase;
+            final ArraySet<PackageStateInternal> packageStates =
+                    (ArraySet<PackageStateInternal>) sus.getPackageStates();
             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
-            final int numPackages = sus.packages.size();
+            final int numPackages = packageStates.size();
             for (int index = 0; index < numPackages; index++) {
-                final PackageSetting ps = sus.packages.valueAt(index);
+                final PackageStateInternal ps = packageStates.valueAt(index);
                 if (ps.getPkg() != null) {
                     int v = ps.getPkg().getTargetSdkVersion();
                     if (v < vers) vers = v;
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 684e6ba..2ef092e 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -3701,7 +3701,7 @@
                     && sharedUserSetting != null) {
                 Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
                         + " (uid=" + sharedUserSetting.mAppId + "):"
-                        + " packages=" + sharedUserSetting.packages);
+                        + " packages=" + sharedUserSetting.getPackageStates());
             }
             if (installedPkgSetting != null) {
                 oldSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(installedPkgSetting);
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelper.java b/services/core/java/com/android/server/pm/PackageAbiHelper.java
index ca7c2db..1dbab90 100644
--- a/services/core/java/com/android/server/pm/PackageAbiHelper.java
+++ b/services/core/java/com/android/server/pm/PackageAbiHelper.java
@@ -18,15 +18,16 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.util.ArraySet;
 import android.util.Pair;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
 import com.android.server.pm.parsing.pkg.ParsedPackage;
+import com.android.server.pm.pkg.PackageStateInternal;
 
 import java.io.File;
-import java.util.Set;
 
 
 
@@ -74,8 +75,8 @@
      *         belonging to the shared user.
      */
     @Nullable
-    String getAdjustedAbiForSharedUser(
-            Set<PackageSetting> packagesForUser, AndroidPackage scannedPackage);
+    String getAdjustedAbiForSharedUser(ArraySet<? extends PackageStateInternal> packagesForUser,
+            AndroidPackage scannedPackage);
 
     /**
      * The native library paths and related properties that should be set on a
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
index 1af508f..73d81ba 100644
--- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
+++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
@@ -34,6 +34,7 @@
 import android.os.FileUtils;
 import android.os.Trace;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.Pair;
 import android.util.Slog;
 
@@ -41,6 +42,7 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
+import com.android.server.pm.pkg.PackageStateInternal;
 
 import dalvik.system.VMRuntime;
 
@@ -48,7 +50,6 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Set;
 
 final class PackageAbiHelperImpl implements PackageAbiHelper {
 
@@ -496,7 +497,8 @@
     @Override
     @Nullable
     public String getAdjustedAbiForSharedUser(
-            Set<PackageSetting> packagesForUser, AndroidPackage scannedPackage) {
+            ArraySet<? extends PackageStateInternal> packagesForUser,
+            AndroidPackage scannedPackage) {
         String requiredInstructionSet = null;
         if (scannedPackage != null) {
             String pkgRawPrimaryCpuAbi = AndroidPackageUtils.getRawPrimaryCpuAbi(scannedPackage);
@@ -505,8 +507,8 @@
             }
         }
 
-        PackageSetting requirer = null;
-        for (PackageSetting ps : packagesForUser) {
+        PackageStateInternal requirer = null;
+        for (PackageStateInternal ps : packagesForUser) {
             // If packagesForUser contains scannedPackage, we skip it. This will happen
             // when scannedPackage is an update of an existing package. Without this check,
             // we will never be able to change the ABI of any package belonging to a shared
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 5c68fac..8f4cef9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2005,7 +2005,7 @@
                         ScanPackageUtils.applyAdjustedAbiToSharedUser(
                                 setting, null /*scannedPackage*/,
                                 mInjector.getAbiHelper().getAdjustedAbiForSharedUser(
-                                setting.packages, null /*scannedPackage*/));
+                                        setting.getPackageStates(), null /*scannedPackage*/));
                 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
                     for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
                         final String codePathString = changedAbiCodePath.get(i);
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 0dae12f..2f56bfe 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -573,9 +573,10 @@
             // Special case: if the sharedUserId capability check failed it could be due to this
             // being the only package in the sharedUserId so far and the lineage being updated to
             // deny the sharedUserId capability of the previous key in the lineage.
-            if (!match && sharedUserSetting.packages.size() == 1
-                    && sharedUserSetting.packages
-                            .valueAt(0).getPackageName().equals(packageName)) {
+            final ArraySet<PackageStateInternal> susPackageStates =
+                    (ArraySet<PackageStateInternal>) sharedUserSetting.getPackageStates();
+            if (!match && susPackageStates.size() == 1
+                    && susPackageStates.valueAt(0).getPackageName().equals(packageName)) {
                 match = true;
             }
             if (!match && compareCompat) {
@@ -605,7 +606,8 @@
             // Iterate over all of the packages in the sharedUserId and ensure any that are signed
             // with a key in this package's lineage have the SHARED_USER_ID capability granted.
             if (parsedSignatures.hasPastSigningCertificates()) {
-                for (PackageSetting shUidPkgSetting : sharedUserSetting.packages) {
+                for (int i = 0; i < susPackageStates.size(); i++) {
+                    PackageStateInternal shUidPkgSetting = susPackageStates.valueAt(i);
                     // if the current package in the sharedUserId is the package being updated then
                     // skip this check as the update may revoke the sharedUserId capability from
                     // the key with which this app was previously signed.
diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java
index 99d9d58..33f0b54 100644
--- a/services/core/java/com/android/server/pm/ScanPackageUtils.java
+++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java
@@ -62,6 +62,7 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
@@ -85,6 +86,7 @@
 import com.android.server.pm.pkg.component.ParsedProvider;
 import com.android.server.pm.pkg.component.ParsedService;
 import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
+import com.android.server.utils.WatchedArraySet;
 
 import dalvik.system.VMRuntime;
 
@@ -94,7 +96,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.Set;
 import java.util.UUID;
 
 /**
@@ -400,7 +401,7 @@
             // code and package path correct.
             changedAbiCodePath = applyAdjustedAbiToSharedUser(oldSharedUserSetting,
                     parsedPackage, packageAbiHelper.getAdjustedAbiForSharedUser(
-                            oldSharedUserSetting.packages, parsedPackage));
+                            oldSharedUserSetting.getPackageStates(), parsedPackage));
         }
 
         parsedPackage.setFactoryTest(isUnderFactoryTest && parsedPackage.getRequestedPermissions()
@@ -891,7 +892,7 @@
 
     /**
      * Applies the adjusted ABI calculated by
-     * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, AndroidPackage)} to all
+     * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(ArraySet, AndroidPackage)} to all
      * relevant packages and settings.
      * @param sharedUserSetting The {@code SharedUserSetting} to adjust
      * @param scannedPackage the package being scanned or null
@@ -904,7 +905,10 @@
             scannedPackage.setPrimaryCpuAbi(adjustedAbi);
         }
         List<String> changedAbiCodePath = null;
-        for (PackageSetting ps : sharedUserSetting.packages) {
+        final WatchedArraySet<PackageSetting> sharedUserPackageSettings =
+                sharedUserSetting.getPackageSettings();
+        for (int i = 0; i < sharedUserPackageSettings.size(); i++) {
+            PackageSetting ps = sharedUserPackageSettings.valueAt(i);
             if (scannedPackage == null
                     || !scannedPackage.getPackageName().equals(ps.getPackageName())) {
                 if (ps.getPrimaryCpuAbi() != null) {
@@ -912,6 +916,7 @@
                 }
 
                 ps.setPrimaryCpuAbi(adjustedAbi);
+                ps.onChanged();
                 if (ps.getPkg() != null) {
                     if (!TextUtils.equals(adjustedAbi,
                             AndroidPackageUtils.getRawPrimaryCpuAbi(ps.getPkg()))) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 5966917..c19e758 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -923,11 +923,30 @@
                 removeKeys.add(entry.getKey());
                 continue;
             }
+            boolean changed = false;
             // remove packages that are no longer installed
-            sus.packages.removeIf(ps -> mPackages.get(ps.getPackageName()) == null);
-            sus.mDisabledPackages.removeIf(
-                    ps -> mDisabledSysPackages.get(ps.getPackageName()) == null);
-            if (sus.packages.isEmpty() && sus.mDisabledPackages.isEmpty()) {
+            WatchedArraySet<PackageSetting> sharedUserPackageSettings = sus.getPackageSettings();
+            for (int i = sharedUserPackageSettings.size() - 1; i >= 0; i--) {
+                PackageSetting ps = sharedUserPackageSettings.valueAt(i);
+                if (mPackages.get(ps.getPackageName()) == null) {
+                    sharedUserPackageSettings.removeAt(i);
+                    changed = true;
+                }
+            }
+            WatchedArraySet<PackageSetting> sharedUserDisabledPackageSettings =
+                    sus.getDisabledPackageSettings();
+            for (int i = sharedUserDisabledPackageSettings.size() - 1; i >= 0; i--) {
+                PackageSetting ps = sharedUserDisabledPackageSettings.valueAt(i);
+                if (mDisabledSysPackages.get(ps.getPackageName()) == null) {
+                    sharedUserDisabledPackageSettings.removeAt(i);
+                    changed = true;
+                }
+            }
+            if (changed) {
+                sus.onChanged();
+            }
+            if (sharedUserPackageSettings.isEmpty()
+                    && sharedUserDisabledPackageSettings.isEmpty()) {
                 removeValues.add(sus);
             }
         }
@@ -1289,7 +1308,8 @@
     }
 
     boolean checkAndPruneSharedUserLPw(SharedUserSetting s, boolean skipCheck) {
-        if (skipCheck || (s.packages.isEmpty() && s.mDisabledPackages.isEmpty())) {
+        if (skipCheck || (s.getPackageStates().isEmpty()
+                && s.getDisabledPackageStates().isEmpty())) {
             if (mSharedUsers.remove(s.name) != null) {
                 removeAppIdLPw(s.mAppId);
                 return true;
@@ -5136,11 +5156,13 @@
                 pw.print(prefix); pw.print("userId="); pw.println(su.mAppId);
 
                 pw.print(prefix); pw.println("Packages");
-                final int numPackages = su.packages.size();
+                final ArraySet<PackageStateInternal> susPackageStates =
+                        (ArraySet<PackageStateInternal>) su.getPackageStates();
+                final int numPackages = susPackageStates.size();
                 for (int i = 0; i < numPackages; i++) {
-                    final PackageSetting ps = su.packages.valueAt(i);
+                    final PackageStateInternal ps = susPackageStates.valueAt(i);
                     if (ps != null) {
-                        pw.print(prefix + "  "); pw.println(ps.toString());
+                        pw.print(prefix + "  "); pw.println(ps);
                     } else {
                         pw.print(prefix + "  "); pw.println("NULL?!");
                     }
diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java
index d0e1e6c..4d0bbc6 100644
--- a/services/core/java/com/android/server/pm/SharedUserSetting.java
+++ b/services/core/java/com/android/server/pm/SharedUserSetting.java
@@ -33,6 +33,7 @@
 import com.android.server.pm.pkg.component.ParsedProcess;
 import com.android.server.pm.pkg.component.ParsedProcessImpl;
 import com.android.server.utils.SnapshotCache;
+import com.android.server.utils.WatchedArraySet;
 
 import libcore.util.EmptyArray;
 
@@ -56,14 +57,14 @@
     /** @see SharedUserApi#getSeInfoTargetSdkVersion() **/
     int seInfoTargetSdkVersion;
 
-    final ArraySet<PackageSetting> packages;
-    private ArraySet<PackageStateInternal> mPackagesSnapshot;
+    private final WatchedArraySet<PackageSetting> mPackages;
+    private final SnapshotCache<WatchedArraySet<PackageSetting>> mPackagesSnapshot;
 
     // It is possible for a system app to leave shared user ID by an update.
     // We need to keep track of the shadowed PackageSettings so that it is possible to uninstall
     // the update and revert the system app back into the original shared user ID.
-    final ArraySet<PackageSetting> mDisabledPackages;
-    private ArraySet<PackageStateInternal> mDisabledPackagesSnapshot;
+    final WatchedArraySet<PackageSetting> mDisabledPackages;
+    private final SnapshotCache<WatchedArraySet<PackageSetting>> mDisabledPackagesSnapshot;
 
     final PackageSignatures signatures = new PackageSignatures();
     Boolean signaturesChanged;
@@ -89,8 +90,12 @@
         uidPrivateFlags = _pkgPrivateFlags;
         name = _name;
         seInfoTargetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
-        packages = new ArraySet<>();
-        mDisabledPackages = new ArraySet<>();
+        mPackages = new WatchedArraySet<>();
+        mPackagesSnapshot = new SnapshotCache.Auto<>(mPackages, mPackages,
+                "SharedUserSetting.packages");
+        mDisabledPackages = new WatchedArraySet<>();
+        mDisabledPackagesSnapshot = new SnapshotCache.Auto<>(mDisabledPackages, mDisabledPackages,
+                "SharedUserSetting.mDisabledPackages");
         processes = new ArrayMap<>();
         mSnapshot = makeCache();
     }
@@ -102,20 +107,10 @@
         mAppId = orig.mAppId;
         uidFlags = orig.uidFlags;
         uidPrivateFlags = orig.uidPrivateFlags;
-        packages = new ArraySet<>(orig.packages);
-        if (!packages.isEmpty()) {
-            mPackagesSnapshot = new ArraySet<>();
-            for (int index = 0; index < packages.size(); index++) {
-                mPackagesSnapshot.add(new PackageSetting(packages.valueAt(index)));
-            }
-        }
-        mDisabledPackages = new ArraySet<>(orig.mDisabledPackages);
-        if (!mDisabledPackages.isEmpty()) {
-            mDisabledPackagesSnapshot = new ArraySet<>();
-            for (int index = 0; index < mDisabledPackages.size(); index++) {
-                mDisabledPackagesSnapshot.add(new PackageSetting(mDisabledPackages.valueAt(index)));
-            }
-        }
+        mPackages = orig.mPackagesSnapshot.snapshot();
+        mPackagesSnapshot = new SnapshotCache.Sealed<>();
+        mDisabledPackages = orig.mDisabledPackagesSnapshot.snapshot();
+        mDisabledPackagesSnapshot = new SnapshotCache.Sealed<>();
         // A SigningDetails seems to consist solely of final attributes, so
         // it is safe to copy the reference.
         signatures.mSigningDetails = orig.signatures.mSigningDetails;
@@ -161,20 +156,22 @@
     }
 
     boolean removePackage(PackageSetting packageSetting) {
-        if (!packages.remove(packageSetting)) {
+        if (!mPackages.remove(packageSetting)) {
             return false;
         }
         // recalculate the pkgFlags for this shared user if needed
         if ((this.getFlags() & packageSetting.getFlags()) != 0) {
             int aggregatedFlags = uidFlags;
-            for (PackageSetting ps : packages) {
+            for (int i = 0; i < mPackages.size(); i++) {
+                PackageSetting ps = mPackages.valueAt(i);
                 aggregatedFlags |= ps.getFlags();
             }
             setFlags(aggregatedFlags);
         }
         if ((this.getPrivateFlags() & packageSetting.getPrivateFlags()) != 0) {
             int aggregatedPrivateFlags = uidPrivateFlags;
-            for (PackageSetting ps : packages) {
+            for (int i = 0; i < mPackages.size(); i++) {
+                PackageSetting ps = mPackages.valueAt(i);
                 aggregatedPrivateFlags |= ps.getPrivateFlags();
             }
             setPrivateFlags(aggregatedPrivateFlags);
@@ -188,10 +185,10 @@
     void addPackage(PackageSetting packageSetting) {
         // If this is the first package added to this shared user, temporarily (until next boot) use
         // its targetSdkVersion when assigning seInfo for the shared user.
-        if ((packages.size() == 0) && (packageSetting.getPkg() != null)) {
+        if ((mPackages.size() == 0) && (packageSetting.getPkg() != null)) {
             seInfoTargetSdkVersion = packageSetting.getPkg().getTargetSdkVersion();
         }
-        if (packages.add(packageSetting)) {
+        if (mPackages.add(packageSetting)) {
             setFlags(this.getFlags() | packageSetting.getFlags());
             setPrivateFlags(this.getPrivateFlags() | packageSetting.getPrivateFlags());
             onChanged();
@@ -204,11 +201,12 @@
     @NonNull
     @Override
     public List<AndroidPackage> getPackages() {
-        if (packages == null || packages.size() == 0) {
+        if (mPackages == null || mPackages.size() == 0) {
             return Collections.emptyList();
         }
-        final ArrayList<AndroidPackage> pkgList = new ArrayList<>(packages.size());
-        for (PackageSetting ps : packages) {
+        final ArrayList<AndroidPackage> pkgList = new ArrayList<>(mPackages.size());
+        for (int i = 0; i < mPackages.size(); i++) {
+            PackageSetting ps = mPackages.valueAt(i);
             if ((ps == null) || (ps.getPkg() == null)) {
                 continue;
             }
@@ -229,10 +227,11 @@
      * restrictive selinux domain.
      */
     public void fixSeInfoLocked() {
-        if (packages == null || packages.size() == 0) {
+        if (mPackages == null || mPackages.size() == 0) {
             return;
         }
-        for (PackageSetting ps : packages) {
+        for (int i = 0; i < mPackages.size(); i++) {
+            PackageSetting ps = mPackages.valueAt(i);
             if ((ps == null) || (ps.getPkg() == null)) {
                 continue;
             }
@@ -242,7 +241,8 @@
             }
         }
 
-        for (PackageSetting ps : packages) {
+        for (int i = 0; i < mPackages.size(); i++) {
+            PackageSetting ps = mPackages.valueAt(i);
             if ((ps == null) || (ps.getPkg() == null)) {
                 continue;
             }
@@ -258,8 +258,8 @@
      */
     public void updateProcesses() {
         processes.clear();
-        for (int i = packages.size() - 1; i >= 0; i--) {
-            final AndroidPackage pkg = packages.valueAt(i).getPkg();
+        for (int i = mPackages.size() - 1; i >= 0; i--) {
+            final AndroidPackage pkg = mPackages.valueAt(i).getPkg();
             if (pkg != null) {
                 addProcesses(pkg.getProcesses());
             }
@@ -269,7 +269,8 @@
     /** Returns userIds which doesn't have any packages with this sharedUserId */
     public int[] getNotInstalledUserIds() {
         int[] excludedUserIds = null;
-        for (PackageSetting ps : packages) {
+        for (int i = 0; i < mPackages.size(); i++) {
+            PackageSetting ps = mPackages.valueAt(i);
             final int[] userIds = ps.getNotInstalledUserIds();
             if (excludedUserIds == null) {
                 excludedUserIds = userIds;
@@ -291,8 +292,8 @@
         this.uidFlags = sharedUser.uidFlags;
         this.uidPrivateFlags = sharedUser.uidPrivateFlags;
         this.seInfoTargetSdkVersion = sharedUser.seInfoTargetSdkVersion;
-        this.packages.clear();
-        this.packages.addAll(sharedUser.packages);
+        this.mPackages.clear();
+        this.mPackages.addAll(sharedUser.mPackages);
         this.signaturesChanged = sharedUser.signaturesChanged;
         if (sharedUser.processes != null) {
             final int numProcs = sharedUser.processes.size();
@@ -335,22 +336,24 @@
         return seInfoTargetSdkVersion;
     }
 
+    public WatchedArraySet<PackageSetting> getPackageSettings() {
+        return mPackages;
+    }
+
+    public WatchedArraySet<PackageSetting> getDisabledPackageSettings() {
+        return mDisabledPackages;
+    }
+
     @NonNull
     @Override
     public ArraySet<? extends PackageStateInternal> getPackageStates() {
-        if (mPackagesSnapshot != null) {
-            return mPackagesSnapshot;
-        }
-        return packages;
+        return mPackages.untrackedStorage();
     }
 
     @NonNull
     @Override
     public ArraySet<? extends PackageStateInternal> getDisabledPackageStates() {
-        if (mDisabledPackagesSnapshot != null) {
-            return mDisabledPackagesSnapshot;
-        }
-        return mDisabledPackages;
+        return mDisabledPackages.untrackedStorage();
     }
 
     @NonNull
diff --git a/services/core/jni/BroadcastRadio/types.h b/services/core/jni/BroadcastRadio/types.h
index 910bb7c..4d286bf 100644
--- a/services/core/jni/BroadcastRadio/types.h
+++ b/services/core/jni/BroadcastRadio/types.h
@@ -30,13 +30,13 @@
 // Keep in sync with STATUS_* constants from RadioManager.java.
 enum class Status : jint {
     OK = 0,
-    ERROR = -0x80000000ll,  // Integer.MIN_VALUE
+    ERROR = -0x80000000LL,   // Integer.MIN_VALUE
     PERMISSION_DENIED = -1,  // -EPERM
-    NO_INIT = -19,  // -ENODEV
-    BAD_VALUE = -22,  // -EINVAL
-    DEAD_OBJECT = -32,  // -EPIPE
-    INVALID_OPERATION = -38,  // -ENOSYS
-    TIMED_OUT = -110,  // -ETIMEDOUT
+    NO_INIT = -19,           // -ENODEV
+    BAD_VALUE = -22,         // -EINVAL
+    DEAD_OBJECT = -32,       // -EPIPE
+    INVALID_OPERATION = -38, // -ENOSYS
+    TIMED_OUT = -110,        // -ETIMEDOUT
 };
 
 // Keep in sync with REGION_* constants from RadioManager.java.
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java
index 0552a83..c12f0a9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java
@@ -274,7 +274,7 @@
         new ValidateNotificationPeople().searchContactsAndLookupNumbers(mockContext, lookupUri);
         verify(mockContentResolver, never()).query(
                 eq(ContactsContract.CommonDataKinds.Phone.CONTENT_URI),
-                eq(new String[] { ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER }),
+                eq(ValidateNotificationPeople.PHONE_LOOKUP_PROJECTION),
                 contains(ContactsContract.Contacts.LOOKUP_KEY),
                 any(),  // selection args
                 isNull());  // sort order
@@ -308,7 +308,7 @@
         // in the case of a phone lookup, return null cursor; that's not an error case
         // and we're not checking the actual storing of the phone data here.
         when(mockContentResolver.query(eq(ContactsContract.CommonDataKinds.Phone.CONTENT_URI),
-                eq(new String[] { ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER }),
+                eq(ValidateNotificationPeople.PHONE_LOOKUP_PROJECTION),
                 contains(ContactsContract.Contacts.LOOKUP_KEY),
                 any(), isNull())).thenReturn(null);
 
@@ -317,7 +317,7 @@
         new ValidateNotificationPeople().searchContactsAndLookupNumbers(mockContext, lookupUri);
         verify(mockContentResolver, times(1)).query(
                 eq(ContactsContract.CommonDataKinds.Phone.CONTENT_URI),
-                eq(new String[] { ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER }),
+                eq(ValidateNotificationPeople.PHONE_LOOKUP_PROJECTION),
                 contains(ContactsContract.Contacts.LOOKUP_KEY),
                 eq(new String[] { "testlookupkey" }),  // selection args
                 isNull());  // sort order
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 2dfc72b..68e90e1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -46,6 +46,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.pm.PackageManager;
 import android.os.Binder;
@@ -284,4 +285,32 @@
         verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(any(),
                 any(), anyInt(), anyInt(), any());
     }
+
+    @Test
+    public void testSetInTouchMode_instrumentedProcessGetPermissionToSwitchTouchMode() {
+        boolean currentTouchMode = mWm.getInTouchMode();
+        int callingPid = Binder.getCallingPid();
+        int callingUid = Binder.getCallingUid();
+        doReturn(false).when(mWm).checkCallingPermission(anyString(), anyString());
+        when(mWm.mAtmService.isInstrumenting(callingPid)).thenReturn(true);
+
+        mWm.setInTouchMode(!currentTouchMode);
+
+        verify(mWm.mInputManager).setInTouchMode(
+                !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true);
+    }
+
+    @Test
+    public void testSetInTouchMode_nonInstrumentedProcessDontGetPermissionToSwitchTouchMode() {
+        boolean currentTouchMode = mWm.getInTouchMode();
+        int callingPid = Binder.getCallingPid();
+        int callingUid = Binder.getCallingUid();
+        doReturn(false).when(mWm).checkCallingPermission(anyString(), anyString());
+        when(mWm.mAtmService.isInstrumenting(callingPid)).thenReturn(false);
+
+        mWm.setInTouchMode(!currentTouchMode);
+
+        verify(mWm.mInputManager).setInTouchMode(
+                !currentTouchMode, callingPid, callingUid, /* hasPermission= */ false);
+    }
 }