Merge Android 14 QPR1

Merged-In: Ieb446f4d7d6c7c8e8d320fb04cb856eeef983873
Bug: 315507370
Change-Id: Ib0257a7a5a8792cf116a1be21daeab289f27c7d5
diff --git a/Android.bp b/Android.bp
index 26a0270..effa39b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -36,6 +36,14 @@
 }
 
 filegroup {
+    name: "AidlsBts",
+    srcs: [
+        "bts/aidl/com/google/android/setupcompat/bts/*.aidl",
+    ],
+    path: "bts/aidl",
+}
+
+filegroup {
     name: "Srcs",
     srcs: [
         "main/java/com/google/android/setupcompat/*.java",
@@ -65,6 +73,14 @@
     path: "main/java",
 }
 
+filegroup {
+    name: "SrcsBts",
+    srcs: [
+        "bts/java/com/google/android/setupcompat/bts/*.java",
+    ],
+    path: "bts/java",
+}
+
 android_library {
     name: "setupcompat",
     manifest: "AndroidManifest.xml",
@@ -88,3 +104,27 @@
         proguard_flags_files: ["proguard.flags"],
     }
 }
+
+android_library {
+    name: "setupcompat_bts",
+    manifest: "AndroidManifest.xml",
+    resource_dirs: [
+        "main/res",
+    ],
+    srcs: [
+        ":Srcs",
+        ":SrcsBts",
+        ":SrcsPartnerConfig",
+        ":Aidls",
+        ":AidlsBts",
+    ],
+    static_libs: [
+        "androidx.annotation_annotation",
+        "error_prone_annotations",
+    ],
+    min_sdk_version: "14",
+    sdk_version: "current",
+    optimize: {
+        proguard_flags_files: ["proguard.flags"],
+    }
+}
diff --git a/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java b/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java
index 8e23c1a..f05023b 100644
--- a/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java
+++ b/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java
@@ -31,6 +31,7 @@
   private final PartnerConfig buttonTextSizeConfig;
   private final PartnerConfig buttonMinHeightConfig;
   private final PartnerConfig buttonTextTypeFaceConfig;
+  private final PartnerConfig buttonTextWeightConfig;
   private final PartnerConfig buttonTextStyleConfig;
   private final PartnerConfig buttonRadiusConfig;
   private final PartnerConfig buttonRippleColorAlphaConfig;
@@ -48,6 +49,7 @@
       PartnerConfig buttonTextSizeConfig,
       PartnerConfig buttonMinHeightConfig,
       PartnerConfig buttonTextTypeFaceConfig,
+      PartnerConfig buttonTextWeightConfig,
       PartnerConfig buttonTextStyleConfig,
       PartnerConfig buttonRadiusConfig,
       PartnerConfig buttonRippleColorAlphaConfig) {
@@ -58,6 +60,7 @@
     this.buttonTextSizeConfig = buttonTextSizeConfig;
     this.buttonMinHeightConfig = buttonMinHeightConfig;
     this.buttonTextTypeFaceConfig = buttonTextTypeFaceConfig;
+    this.buttonTextWeightConfig = buttonTextWeightConfig;
     this.buttonTextStyleConfig = buttonTextStyleConfig;
     this.buttonBackgroundConfig = buttonBackgroundConfig;
     this.buttonDisableAlphaConfig = buttonDisableAlphaConfig;
@@ -112,6 +115,10 @@
     return buttonTextTypeFaceConfig;
   }
 
+  public PartnerConfig getButtonTextWeightConfig() {
+    return buttonTextWeightConfig;
+  }
+
   public PartnerConfig getButtonTextStyleConfig() {
     return buttonTextStyleConfig;
   }
@@ -137,6 +144,7 @@
     private PartnerConfig buttonTextSizeConfig = null;
     private PartnerConfig buttonMinHeight = null;
     private PartnerConfig buttonTextTypeFaceConfig = null;
+    private PartnerConfig buttonTextWeightConfig = null;
     private PartnerConfig buttonTextStyleConfig = null;
     private PartnerConfig buttonRadiusConfig = null;
     private PartnerConfig buttonRippleColorAlphaConfig = null;
@@ -200,6 +208,11 @@
       return this;
     }
 
+    public Builder setTextWeightConfig(PartnerConfig buttonTextWeightFaceConfig) {
+      this.buttonTextWeightConfig = buttonTextWeightFaceConfig;
+      return this;
+    }
+
     public Builder setTextStyleConfig(PartnerConfig buttonTextStyleConfig) {
       this.buttonTextStyleConfig = buttonTextStyleConfig;
       return this;
@@ -233,6 +246,7 @@
           buttonTextSizeConfig,
           buttonMinHeight,
           buttonTextTypeFaceConfig,
+          buttonTextWeightConfig,
           buttonTextStyleConfig,
           buttonRadiusConfig,
           buttonRippleColorAlphaConfig);
diff --git a/main/java/com/google/android/setupcompat/template/FooterBarMixin.java b/main/java/com/google/android/setupcompat/template/FooterBarMixin.java
index 2268b1e..2c8cb8c 100644
--- a/main/java/com/google/android/setupcompat/template/FooterBarMixin.java
+++ b/main/java/com/google/android/setupcompat/template/FooterBarMixin.java
@@ -407,6 +407,7 @@
             .setTextSizeConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_SIZE)
             .setButtonMinHeight(PartnerConfig.CONFIG_FOOTER_BUTTON_MIN_HEIGHT)
             .setTextTypeFaceConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_FONT_FAMILY)
+            .setTextWeightConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_FONT_WEIGHT)
             .setTextStyleConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_STYLE)
             .build();
 
@@ -485,6 +486,7 @@
             .setTextSizeConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_SIZE)
             .setButtonMinHeight(PartnerConfig.CONFIG_FOOTER_BUTTON_MIN_HEIGHT)
             .setTextTypeFaceConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_FONT_FAMILY)
+            .setTextWeightConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_FONT_WEIGHT)
             .setTextStyleConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_STYLE)
             .build();
 
diff --git a/main/java/com/google/android/setupcompat/template/FooterButtonStyleUtils.java b/main/java/com/google/android/setupcompat/template/FooterButtonStyleUtils.java
index 476d45b..c4818d9 100644
--- a/main/java/com/google/android/setupcompat/template/FooterButtonStyleUtils.java
+++ b/main/java/com/google/android/setupcompat/template/FooterButtonStyleUtils.java
@@ -16,6 +16,9 @@
 
 package com.google.android.setupcompat.template;
 
+import static com.google.android.setupcompat.partnerconfig.PartnerConfigHelper.isFontWeightEnabled;
+
+import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -35,6 +38,7 @@
 import android.view.ViewGroup;
 import android.widget.Button;
 import androidx.annotation.ColorInt;
+import androidx.annotation.Nullable;
 import com.google.android.setupcompat.R;
 import com.google.android.setupcompat.internal.FooterButtonPartnerConfig;
 import com.google.android.setupcompat.internal.Preconditions;
@@ -46,6 +50,9 @@
 public class FooterButtonStyleUtils {
   private static final float DEFAULT_DISABLED_ALPHA = 0.26f;
 
+  // android.graphics.fonts.FontStyle.FontStyle#FONT_WEIGHT_NORMAL
+  private static final int FONT_WEIGHT_NORMAL = 400;
+
   private static final HashMap<Integer, ColorStateList> defaultTextColor = new HashMap<>();
 
   /** Apply the partner primary button style to given {@code button}. */
@@ -67,6 +74,7 @@
             .setTextSizeConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_SIZE)
             .setButtonMinHeight(PartnerConfig.CONFIG_FOOTER_BUTTON_MIN_HEIGHT)
             .setTextTypeFaceConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_FONT_FAMILY)
+            .setTextWeightConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_FONT_WEIGHT)
             .setTextStyleConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_STYLE)
             .build();
     applyButtonPartnerResources(
@@ -104,6 +112,7 @@
             .setTextSizeConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_SIZE)
             .setButtonMinHeight(PartnerConfig.CONFIG_FOOTER_BUTTON_MIN_HEIGHT)
             .setTextTypeFaceConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_FONT_FAMILY)
+            .setTextWeightConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_FONT_WEIGHT)
             .setTextStyleConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_STYLE)
             .build();
     applyButtonPartnerResources(
@@ -121,7 +130,7 @@
       boolean isButtonIconAtEnd,
       FooterButtonPartnerConfig footerButtonPartnerConfig) {
 
-    // Save defualt text color for the partner config disable button text color not available.
+    // Save default text color for the partner config disable button text color not available.
     saveButtonDefaultTextColor(button);
 
     // If dynamic color enabled, these colors won't be overrode by partner config.
@@ -158,6 +167,7 @@
         context,
         button,
         footerButtonPartnerConfig.getButtonTextTypeFaceConfig(),
+        footerButtonPartnerConfig.getButtonTextWeightConfig(),
         footerButtonPartnerConfig.getButtonTextStyleConfig());
     FooterButtonStyleUtils.updateButtonRadiusWithPartnerConfig(
         context, button, footerButtonPartnerConfig.getButtonRadiusConfig());
@@ -340,10 +350,12 @@
     }
   }
 
+  @SuppressLint("NewApi") // Applying partner config should be guarded before Android S
   static void updateButtonTypeFaceWithPartnerConfig(
       Context context,
       Button button,
       PartnerConfig buttonTextTypeFaceConfig,
+      PartnerConfig buttonTextWeightConfig,
       PartnerConfig buttonTextStyleConfig) {
     String fontFamilyName =
         PartnerConfigHelper.get(context).getString(context, buttonTextTypeFaceConfig);
@@ -354,7 +366,19 @@
           PartnerConfigHelper.get(context)
               .getInteger(context, buttonTextStyleConfig, Typeface.NORMAL);
     }
-    Typeface font = Typeface.create(fontFamilyName, textStyleValue);
+
+    Typeface font;
+    int textWeightValue;
+    if (isFontWeightEnabled(context)
+        && PartnerConfigHelper.get(context).isPartnerConfigAvailable(buttonTextWeightConfig)) {
+      textWeightValue =
+          PartnerConfigHelper.get(context)
+              .getInteger(context, buttonTextWeightConfig, FONT_WEIGHT_NORMAL);
+      Typeface fontFamily = Typeface.create(fontFamilyName, textStyleValue);
+      font = Typeface.create(fontFamily, textWeightValue, /* italic= */ false);
+    } else {
+      font = Typeface.create(fontFamilyName, textStyleValue);
+    }
     if (font != null) {
       button.setTypeface(font);
     }
@@ -389,7 +413,7 @@
     }
 
     if (icon != null) {
-      // TODO: restrict the icons to a reasonable size
+      // TODO: b/120488979 - restrict the icons to a reasonable size
       int h = icon.getIntrinsicHeight();
       int w = icon.getIntrinsicWidth();
       icon.setBounds(0, 0, w, h);
@@ -429,6 +453,7 @@
   }
 
   /** Gets {@code GradientDrawable} from given {@code button}. */
+  @Nullable
   public static GradientDrawable getGradientDrawable(Button button) {
     // RippleDrawable is available after sdk 21, InsetDrawable#getDrawable is available after
     // sdk 19. So check the sdk is higher than sdk 21 and since Stencil customization provider only
@@ -449,6 +474,7 @@
     return null;
   }
 
+  @Nullable
   static RippleDrawable getRippleDrawable(Button button) {
     // RippleDrawable is available after sdk 21. And because on lower sdk the RippleDrawable is
     // unavailable. Since Stencil customization provider only works on Q+, there is no need to
diff --git a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java
index ea0dfd7..4f752d7 100644
--- a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java
@@ -57,6 +57,10 @@
   CONFIG_FOOTER_BUTTON_FONT_FAMILY(
       PartnerConfigKey.KEY_FOOTER_BUTTON_FONT_FAMILY, ResourceType.STRING),
 
+  // The font weight used in footer buttons.
+  CONFIG_FOOTER_BUTTON_FONT_WEIGHT(
+      PartnerConfigKey.KEY_FOOTER_BUTTON_FONT_WEIGHT, ResourceType.INTEGER),
+
   // The icon for "add another" action. Can be "@null" for no icon.
   CONFIG_FOOTER_BUTTON_ICON_ADD_ANOTHER(
       PartnerConfigKey.KEY_FOOTER_BUTTON_ICON_ADD_ANOTHER, ResourceType.DRAWABLE),
@@ -182,6 +186,9 @@
   // Font family of the header
   CONFIG_HEADER_FONT_FAMILY(PartnerConfigKey.KEY_HEADER_FONT_FAMILY, ResourceType.STRING),
 
+  // Font weight of the header
+  CONFIG_HEADER_FONT_WEIGHT(PartnerConfigKey.KEY_HEADER_FONT_WEIGHT, ResourceType.INTEGER),
+
   // Margin top of the header text
   CONFIG_HEADER_TEXT_MARGIN_TOP(
       PartnerConfigKey.KEY_HEADER_TEXT_MARGIN_TOP, ResourceType.DIMENSION),
@@ -239,6 +246,10 @@
   // Font family of the description
   CONFIG_DESCRIPTION_FONT_FAMILY(PartnerConfigKey.KEY_DESCRIPTION_FONT_FAMILY, ResourceType.STRING),
 
+  // Font weight of the description
+  CONFIG_DESCRIPTION_FONT_WEIGHT(
+      PartnerConfigKey.KEY_DESCRIPTION_FONT_WEIGHT, ResourceType.INTEGER),
+
   // Font family of the link text
   CONFIG_DESCRIPTION_LINK_FONT_FAMILY(
       PartnerConfigKey.KEY_DESCRIPTION_LINK_FONT_FAMILY, ResourceType.STRING),
diff --git a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java
index 96a4317..e08cfa6 100644
--- a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java
@@ -69,6 +69,9 @@
   public static final String IS_NEUTRAL_BUTTON_STYLE_ENABLED_METHOD = "isNeutralButtonStyleEnabled";
 
   @VisibleForTesting
+  public static final String IS_FONT_WEIGHT_ENABLED_METHOD = "isFontWeightEnabled";
+
+  @VisibleForTesting
   public static final String IS_EMBEDDED_ACTIVITY_ONE_PANE_ENABLED_METHOD =
       "isEmbeddedActivityOnePaneEnabled";
 
@@ -91,6 +94,8 @@
 
   @VisibleForTesting public static Bundle applyNeutralButtonStyleBundle = null;
 
+  @VisibleForTesting public static Bundle applyFontWeightBundle = null;
+
   @VisibleForTesting public static Bundle applyEmbeddedActivityOnePaneBundle = null;
 
   @VisibleForTesting public static Bundle suwDefaultThemeBundle = null;
@@ -644,7 +649,7 @@
     return inputResourceEntry;
   }
 
-  // Check the embedded acitvity flag and replace the inputResourceEntry.resourceName &
+  // Check the embedded activity flag and replace the inputResourceEntry.resourceName &
   // inputResourceEntry.resourceId after U.
   ResourceEntry embeddedActivityResourceEntryDefaultValue(
       Context context, ResourceEntry inputResourceEntry) {
@@ -880,6 +885,29 @@
         && applyNeutralButtonStyleBundle.getBoolean(IS_NEUTRAL_BUTTON_STYLE_ENABLED_METHOD, false));
   }
 
+  /** Returns true if the SetupWizard supports the font weight customization during setup flow. */
+  public static boolean isFontWeightEnabled(@NonNull Context context) {
+    if (applyFontWeightBundle == null) {
+      try {
+        applyFontWeightBundle =
+            context
+                .getContentResolver()
+                .call(
+                    getContentUri(),
+                    IS_FONT_WEIGHT_ENABLED_METHOD,
+                    /* arg= */ null,
+                    /* extras= */ null);
+      } catch (IllegalArgumentException | SecurityException exception) {
+        Log.w(TAG, "Font weight supporting status unknown; return as false.");
+        applyFontWeightBundle = null;
+        return false;
+      }
+    }
+
+    return (applyFontWeightBundle != null
+        && applyFontWeightBundle.getBoolean(IS_FONT_WEIGHT_ENABLED_METHOD, true));
+  }
+
   /**
    * Returns the system property to indicate the transition settings is set by Glif theme rather
    * than the client.
diff --git a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java
index a5f9c3a..1dca0cd 100644
--- a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java
@@ -34,6 +34,7 @@
   PartnerConfigKey.KEY_FOOTER_BAR_PADDING_START,
   PartnerConfigKey.KEY_FOOTER_BAR_PADDING_END,
   PartnerConfigKey.KEY_FOOTER_BUTTON_FONT_FAMILY,
+  PartnerConfigKey.KEY_FOOTER_BUTTON_FONT_WEIGHT,
   PartnerConfigKey.KEY_FOOTER_BUTTON_ICON_ADD_ANOTHER,
   PartnerConfigKey.KEY_FOOTER_BUTTON_ICON_CANCEL,
   PartnerConfigKey.KEY_FOOTER_BUTTON_ICON_CLEAR,
@@ -67,6 +68,7 @@
   PartnerConfigKey.KEY_HEADER_TEXT_SIZE,
   PartnerConfigKey.KEY_HEADER_TEXT_COLOR,
   PartnerConfigKey.KEY_HEADER_FONT_FAMILY,
+  PartnerConfigKey.KEY_HEADER_FONT_WEIGHT,
   PartnerConfigKey.KEY_HEADER_AREA_BACKGROUND_COLOR,
   PartnerConfigKey.KEY_HEADER_TEXT_MARGIN_TOP,
   PartnerConfigKey.KEY_HEADER_TEXT_MARGIN_BOTTOM,
@@ -83,6 +85,7 @@
   PartnerConfigKey.KEY_DESCRIPTION_TEXT_COLOR,
   PartnerConfigKey.KEY_DESCRIPTION_LINK_TEXT_COLOR,
   PartnerConfigKey.KEY_DESCRIPTION_FONT_FAMILY,
+  PartnerConfigKey.KEY_DESCRIPTION_FONT_WEIGHT,
   PartnerConfigKey.KEY_DESCRIPTION_LINK_FONT_FAMILY,
   PartnerConfigKey.KEY_DESCRIPTION_TEXT_MARGIN_TOP,
   PartnerConfigKey.KEY_DESCRIPTION_TEXT_MARGIN_BOTTOM,
@@ -182,6 +185,9 @@
   // available in the system. Font references (@font or @xml) are not allowed.
   String KEY_FOOTER_BUTTON_FONT_FAMILY = "setup_compat_footer_button_font_family";
 
+  // The font weight used in footer buttons.
+  String KEY_FOOTER_BUTTON_FONT_WEIGHT = "setup_compat_footer_button_font_weight";
+
   // The icon for "add another" action. Can be "@null" for no icon.
   String KEY_FOOTER_BUTTON_ICON_ADD_ANOTHER = "setup_compat_footer_button_icon_add_another";
 
@@ -283,6 +289,9 @@
   // Font family of the header
   String KEY_HEADER_FONT_FAMILY = "setup_design_header_font_family";
 
+  // Font weight of the header
+  String KEY_HEADER_FONT_WEIGHT = "setup_design_header_font_weight";
+
   // Margin top of the header text
   String KEY_HEADER_TEXT_MARGIN_TOP = "setup_design_header_text_margin_top";
 
@@ -333,6 +342,9 @@
   // Font family of the description
   String KEY_DESCRIPTION_FONT_FAMILY = "setup_design_description_font_family";
 
+  // Font weight of the description
+  String KEY_DESCRIPTION_FONT_WEIGHT = "setup_design_description_font_weight";
+
   // Font family of the link text
   String KEY_DESCRIPTION_LINK_FONT_FAMILY = "setup_design_description_link_font_family";