[automerger skipped] Add lint baseline to address NewApi errors am: 71f3b1924f am: c0d3058b8c am: ed0da29ec4 -s ours

am skip reason: skip tag Change-Id I21d7d6d9794b94083a4f4f33a3c65c2c6b0488a7 with SHA-1 b029e75df7 is already in history

Original change: https://android-review.googlesource.com/c/platform/external/setupcompat/+/1675512

Change-Id: I839006323b40811fd49ca7a9d194958d189701ba
diff --git a/exempting_lint_checks.txt b/exempting_lint_checks.txt
new file mode 100644
index 0000000..f875ad3
--- /dev/null
+++ b/exempting_lint_checks.txt
@@ -0,0 +1,4 @@
+third_party/java_src/android_libs/setupcompat/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java: CustomViewStyleable: attrs, R.styleable.SucPartnerCustomizationLayout, defStyleAttr, 0);
+third_party/java_src/android_libs/setupcompat/main/java/com/google/android/setupcompat/internal/TemplateLayout.java: CustomViewStyleable: getContext().obtainStyledAttributes(attrs, R.styleable.SucTemplateLayout, defStyleAttr, 0);
+third_party/java_src/android_libs/setupcompat/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java: CustomViewStyleable: attrs, R.styleable.SucPartnerCustomizationLayout, defStyleAttr, 0);
+third_party/java_src/android_libs/setupcompat/main/java/com/google/android/setupcompat/internal/TemplateLayout.java: CustomViewStyleable: getContext().obtainStyledAttributes(attrs, R.styleable.SucTemplateLayout, defStyleAttr, 0);
diff --git a/grandfathered_lint_checks.txt b/grandfathered_lint_checks.txt
deleted file mode 100644
index e69de29..0000000
--- a/grandfathered_lint_checks.txt
+++ /dev/null
diff --git a/lint-baseline.xml b/lint-baseline.xml
index ac87760..43e81f8 100644
--- a/lint-baseline.xml
+++ b/lint-baseline.xml
@@ -30,7 +30,7 @@
         errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="external/setupcompat/main/res/values/styles.xml"
-            line="52"
+            line="54"
             column="15"/>
     </issue>
 
@@ -41,7 +41,7 @@
         errorLine2="                                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="external/setupcompat/main/res/values/styles.xml"
-            line="58"
+            line="60"
             column="59"/>
     </issue>
 
@@ -52,7 +52,7 @@
         errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="external/setupcompat/main/res/values/styles.xml"
-            line="66"
+            line="68"
             column="15"/>
     </issue>
 
diff --git a/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java b/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java
index fac4b39..3f3eb9d 100644
--- a/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java
+++ b/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java
@@ -83,6 +83,9 @@
   }
 
   private void init(AttributeSet attrs, int defStyleAttr) {
+    if (isInEditMode()) {
+      return;
+    }
 
     TypedArray a =
         getContext()
@@ -132,15 +135,13 @@
   @Override
   protected void onBeforeTemplateInflated(AttributeSet attrs, int defStyleAttr) {
 
-    boolean isSetupFlow;
-
     // Sets default value to true since this timing
     // before PartnerCustomization members initialization
     usePartnerResourceAttr = true;
 
     activity = lookupActivityFromContext(getContext());
 
-    isSetupFlow = WizardManagerHelper.isAnySetupWizard(activity.getIntent());
+    boolean isSetupFlow = WizardManagerHelper.isAnySetupWizard(activity.getIntent());
 
     TypedArray a =
         getContext()
@@ -216,7 +217,7 @@
     }
   }
 
-  private static Activity lookupActivityFromContext(Context context) {
+  public static Activity lookupActivityFromContext(Context context) {
     if (context instanceof Activity) {
       return (Activity) context;
     } else if (context instanceof ContextWrapper) {
diff --git a/main/java/com/google/android/setupcompat/internal/FallbackThemeWrapper.java b/main/java/com/google/android/setupcompat/internal/FallbackThemeWrapper.java
index af17a62..574f614 100644
--- a/main/java/com/google/android/setupcompat/internal/FallbackThemeWrapper.java
+++ b/main/java/com/google/android/setupcompat/internal/FallbackThemeWrapper.java
@@ -18,8 +18,8 @@
 
 import android.content.Context;
 import android.content.res.Resources.Theme;
-import androidx.annotation.StyleRes;
 import android.view.ContextThemeWrapper;
+import androidx.annotation.StyleRes;
 
 /**
  * Same as {@link ContextThemeWrapper}, but the base context's theme attributes take precedence over
diff --git a/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java b/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java
index 39b50cf..08d76e9 100644
--- a/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java
+++ b/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java
@@ -27,7 +27,9 @@
   private final PartnerConfig buttonIconConfig;
   private final PartnerConfig buttonTextColorConfig;
   private final PartnerConfig buttonTextSizeConfig;
+  private final PartnerConfig buttonMinHeightConfig;
   private final PartnerConfig buttonTextTypeFaceConfig;
+  private final PartnerConfig buttonTextStyleConfig;
   private final PartnerConfig buttonRadiusConfig;
   private final PartnerConfig buttonRippleColorAlphaConfig;
   private final int partnerTheme;
@@ -40,14 +42,18 @@
       PartnerConfig buttonIconConfig,
       PartnerConfig buttonTextColorConfig,
       PartnerConfig buttonTextSizeConfig,
+      PartnerConfig buttonMinHeightConfig,
       PartnerConfig buttonTextTypeFaceConfig,
+      PartnerConfig buttonTextStyleConfig,
       PartnerConfig buttonRadiusConfig,
       PartnerConfig buttonRippleColorAlphaConfig) {
     this.partnerTheme = partnerTheme;
 
     this.buttonTextColorConfig = buttonTextColorConfig;
     this.buttonTextSizeConfig = buttonTextSizeConfig;
+    this.buttonMinHeightConfig = buttonMinHeightConfig;
     this.buttonTextTypeFaceConfig = buttonTextTypeFaceConfig;
+    this.buttonTextStyleConfig = buttonTextStyleConfig;
     this.buttonBackgroundConfig = buttonBackgroundConfig;
     this.buttonDisableAlphaConfig = buttonDisableAlphaConfig;
     this.buttonDisableBackgroundConfig = buttonDisableBackgroundConfig;
@@ -80,6 +86,10 @@
     return buttonTextColorConfig;
   }
 
+  public PartnerConfig getButtonMinHeightConfig() {
+    return buttonMinHeightConfig;
+  }
+
   public PartnerConfig getButtonTextSizeConfig() {
     return buttonTextSizeConfig;
   }
@@ -88,6 +98,10 @@
     return buttonTextTypeFaceConfig;
   }
 
+  public PartnerConfig getButtonTextStyleConfig() {
+    return buttonTextStyleConfig;
+  }
+
   public PartnerConfig getButtonRadiusConfig() {
     return buttonRadiusConfig;
   }
@@ -105,7 +119,9 @@
     private PartnerConfig buttonIconConfig = null;
     private PartnerConfig buttonTextColorConfig = null;
     private PartnerConfig buttonTextSizeConfig = null;
+    private PartnerConfig buttonMinHeight = null;
     private PartnerConfig buttonTextTypeFaceConfig = null;
+    private PartnerConfig buttonTextStyleConfig = null;
     private PartnerConfig buttonRadiusConfig = null;
     private PartnerConfig buttonRippleColorAlphaConfig = null;
     private int partnerTheme;
@@ -146,11 +162,21 @@
       return this;
     }
 
+    public Builder setButtonMinHeight(PartnerConfig buttonMinHeightConfig) {
+      this.buttonMinHeight = buttonMinHeightConfig;
+      return this;
+    }
+
     public Builder setTextTypeFaceConfig(PartnerConfig buttonTextTypeFaceConfig) {
       this.buttonTextTypeFaceConfig = buttonTextTypeFaceConfig;
       return this;
     }
 
+    public Builder setTextStyleConfig(PartnerConfig buttonTextStyleConfig) {
+      this.buttonTextStyleConfig = buttonTextStyleConfig;
+      return this;
+    }
+
     public Builder setButtonRadiusConfig(PartnerConfig buttonRadiusConfig) {
       this.buttonRadiusConfig = buttonRadiusConfig;
       return this;
@@ -175,7 +201,9 @@
           buttonIconConfig,
           buttonTextColorConfig,
           buttonTextSizeConfig,
+          buttonMinHeight,
           buttonTextTypeFaceConfig,
+          buttonTextStyleConfig,
           buttonRadiusConfig,
           buttonRippleColorAlphaConfig);
     }
diff --git a/main/java/com/google/android/setupcompat/internal/PersistableBundles.java b/main/java/com/google/android/setupcompat/internal/PersistableBundles.java
index 1197645..f02265a 100644
--- a/main/java/com/google/android/setupcompat/internal/PersistableBundles.java
+++ b/main/java/com/google/android/setupcompat/internal/PersistableBundles.java
@@ -29,7 +29,7 @@
 import java.util.List;
 
 /** Contains utility methods related to {@link PersistableBundle}. */
-@TargetApi(VERSION_CODES.Q)
+@TargetApi(VERSION_CODES.LOLLIPOP_MR1)
 public final class PersistableBundles {
 
   /**
diff --git a/main/java/com/google/android/setupcompat/internal/SetupCompatServiceInvoker.java b/main/java/com/google/android/setupcompat/internal/SetupCompatServiceInvoker.java
index a1ca156..779cc8a 100644
--- a/main/java/com/google/android/setupcompat/internal/SetupCompatServiceInvoker.java
+++ b/main/java/com/google/android/setupcompat/internal/SetupCompatServiceInvoker.java
@@ -20,8 +20,8 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.os.RemoteException;
-import androidx.annotation.VisibleForTesting;
 import android.util.Log;
+import androidx.annotation.VisibleForTesting;
 import com.google.android.setupcompat.ISetupCompatService;
 import com.google.android.setupcompat.logging.internal.SetupMetricsLoggingConstants.MetricType;
 import java.util.concurrent.ExecutorService;
@@ -68,7 +68,7 @@
       } else {
         Log.w(TAG, "logMetric failed since service reference is null. Are the permissions valid?");
       }
-    } catch (InterruptedException | TimeoutException | RemoteException e) {
+    } catch (InterruptedException | TimeoutException | RemoteException | IllegalStateException e) {
       Log.e(TAG, String.format("Exception occurred while trying to log metric = [%s]", args), e);
     }
   }
diff --git a/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java b/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java
index 2043a81..12c0a92 100644
--- a/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java
+++ b/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java
@@ -23,10 +23,10 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.Looper;
+import android.util.Log;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
-import android.util.Log;
 import com.google.android.setupcompat.ISetupCompatService;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
diff --git a/main/java/com/google/android/setupcompat/internal/TemplateLayout.java b/main/java/com/google/android/setupcompat/internal/TemplateLayout.java
index 34179d6..25a3c5b 100644
--- a/main/java/com/google/android/setupcompat/internal/TemplateLayout.java
+++ b/main/java/com/google/android/setupcompat/internal/TemplateLayout.java
@@ -20,15 +20,15 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.os.Build.VERSION_CODES;
-import androidx.annotation.Keep;
-import androidx.annotation.LayoutRes;
-import androidx.annotation.StyleRes;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
+import androidx.annotation.Keep;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.StyleRes;
 import com.google.android.setupcompat.R;
 import com.google.android.setupcompat.template.Mixin;
 import java.util.HashMap;
diff --git a/main/java/com/google/android/setupcompat/logging/internal/PartnerCustomizedResourceListMetric.java b/main/java/com/google/android/setupcompat/logging/internal/PartnerCustomizedResourceListMetric.java
index 7d0b731..2aa1240 100644
--- a/main/java/com/google/android/setupcompat/logging/internal/PartnerCustomizedResourceListMetric.java
+++ b/main/java/com/google/android/setupcompat/logging/internal/PartnerCustomizedResourceListMetric.java
@@ -30,24 +30,28 @@
 @TargetApi(VERSION_CODES.Q)
 public class PartnerCustomizedResourceListMetric {
 
-  public static void logMetrics(Context context, String screenName, Bundle bundle) {
+  public static void logMetrics(Context context, String deviceDisplayName, Bundle bundle) {
     PersistableBundle logBundle =
-        buildLogBundleFromResourceConfigBundle(context.getPackageName(), bundle);
+        buildLogBundleFromResourceConfigBundle(context.getPackageName(), deviceDisplayName, bundle);
     if (!logBundle.isEmpty()) {
       SetupMetricsLogger.logCustomEvent(
           context,
-          CustomEvent.create(MetricKey.get("PartnerCustomizationResource", screenName), logBundle));
+          CustomEvent.create(
+              MetricKey.get("PartnerCustomizationResource", "NoScreenName"), logBundle));
     }
   }
 
   @VisibleForTesting
   public static PersistableBundle buildLogBundleFromResourceConfigBundle(
-      String defaultPackageName, Bundle resourceConfigBundle) {
+      String defaultPackageName, String deviceDisplayName, Bundle resourceConfigBundle) {
     PersistableBundle persistableBundle = new PersistableBundle();
+    persistableBundle.putString("deviceDisplayName", deviceDisplayName);
     for (String key : resourceConfigBundle.keySet()) {
       Bundle resourceExtra = resourceConfigBundle.getBundle(key);
       if (!resourceExtra.getString("packageName", defaultPackageName).equals(defaultPackageName)) {
         persistableBundle.putBoolean(resourceExtra.getString("resourceName", key), true);
+      } else {
+        persistableBundle.putBoolean(resourceExtra.getString("resourceName", key), false);
       }
     }
 
diff --git a/main/java/com/google/android/setupcompat/template/FooterActionButton.java b/main/java/com/google/android/setupcompat/template/FooterActionButton.java
index bb26d19..86a06d9 100644
--- a/main/java/com/google/android/setupcompat/template/FooterActionButton.java
+++ b/main/java/com/google/android/setupcompat/template/FooterActionButton.java
@@ -18,11 +18,11 @@
 
 import android.annotation.SuppressLint;
 import android.content.Context;
-import androidx.annotation.Nullable;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.Button;
+import androidx.annotation.Nullable;
 
 /** Button that can react to touch when disabled. */
 public class FooterActionButton extends Button {
diff --git a/main/java/com/google/android/setupcompat/template/FooterBarMixin.java b/main/java/com/google/android/setupcompat/template/FooterBarMixin.java
index bc9e5c1..0952f0b 100644
--- a/main/java/com/google/android/setupcompat/template/FooterBarMixin.java
+++ b/main/java/com/google/android/setupcompat/template/FooterBarMixin.java
@@ -34,16 +34,6 @@
 import android.os.Build;
 import android.os.Build.VERSION_CODES;
 import android.os.PersistableBundle;
-import androidx.annotation.AttrRes;
-import androidx.annotation.CallSuper;
-import androidx.annotation.ColorInt;
-import androidx.annotation.IdRes;
-import androidx.annotation.LayoutRes;
-import androidx.annotation.MainThread;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StyleRes;
-import androidx.annotation.VisibleForTesting;
 import android.util.AttributeSet;
 import android.util.StateSet;
 import android.util.TypedValue;
@@ -54,6 +44,16 @@
 import android.widget.Button;
 import android.widget.LinearLayout;
 import android.widget.LinearLayout.LayoutParams;
+import androidx.annotation.AttrRes;
+import androidx.annotation.CallSuper;
+import androidx.annotation.ColorInt;
+import androidx.annotation.IdRes;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.MainThread;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StyleRes;
+import androidx.annotation.VisibleForTesting;
 import com.google.android.setupcompat.PartnerCustomizationLayout;
 import com.google.android.setupcompat.R;
 import com.google.android.setupcompat.internal.FooterButtonPartnerConfig;
@@ -273,6 +273,17 @@
         footerBarPaddingTop,
         buttonContainer.getPaddingRight(),
         footerBarPaddingBottom);
+
+    if (PartnerConfigHelper.get(context)
+        .isPartnerConfigAvailable(PartnerConfig.CONFIG_FOOTER_BAR_MIN_HEIGHT)) {
+      int minHeight =
+          (int)
+              PartnerConfigHelper.get(context)
+                  .getDimension(context, PartnerConfig.CONFIG_FOOTER_BAR_MIN_HEIGHT);
+      if (minHeight > 0) {
+        buttonContainer.setMinimumHeight(minHeight);
+      }
+    }
   }
 
   /**
@@ -310,7 +321,9 @@
             .setButtonRippleColorAlphaConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_RIPPLE_COLOR_ALPHA)
             .setTextColorConfig(PartnerConfig.CONFIG_FOOTER_PRIMARY_BUTTON_TEXT_COLOR)
             .setTextSizeConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_SIZE)
+            .setButtonMinHeight(PartnerConfig.CONFIG_FOOTER_BUTTON_MIN_HEIGHT)
             .setTextTypeFaceConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_FONT_FAMILY)
+            .setTextStyleConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_STYLE)
             .build();
 
     FooterActionButton button = inflateButton(footerButton, footerButtonPartnerConfig);
@@ -366,7 +379,9 @@
             .setButtonRippleColorAlphaConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_RIPPLE_COLOR_ALPHA)
             .setTextColorConfig(PartnerConfig.CONFIG_FOOTER_SECONDARY_BUTTON_TEXT_COLOR)
             .setTextSizeConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_SIZE)
+            .setButtonMinHeight(PartnerConfig.CONFIG_FOOTER_BUTTON_MIN_HEIGHT)
             .setTextTypeFaceConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_FONT_FAMILY)
+            .setTextStyleConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_STYLE)
             .build();
 
     FooterActionButton button = inflateButton(footerButton, footerButtonPartnerConfig);
@@ -548,8 +563,12 @@
         button, footerButtonPartnerConfig.getButtonTextColorConfig());
     updateButtonTextSizeWithPartnerConfig(
         button, footerButtonPartnerConfig.getButtonTextSizeConfig());
+    updateButtonMinHeightWithPartnerConfig(
+        button, footerButtonPartnerConfig.getButtonMinHeightConfig());
     updateButtonTypeFaceWithPartnerConfig(
-        button, footerButtonPartnerConfig.getButtonTextTypeFaceConfig());
+        button,
+        footerButtonPartnerConfig.getButtonTextTypeFaceConfig(),
+        footerButtonPartnerConfig.getButtonTextStyleConfig());
     updateButtonBackgroundWithPartnerConfig(
         button,
         footerButtonPartnerConfig.getButtonBackgroundConfig(),
@@ -583,11 +602,28 @@
     }
   }
 
+  private void updateButtonMinHeightWithPartnerConfig(
+      Button button, PartnerConfig buttonMinHeightConfig) {
+    if (PartnerConfigHelper.get(context).isPartnerConfigAvailable(buttonMinHeightConfig)) {
+      float size = PartnerConfigHelper.get(context).getDimension(context, buttonMinHeightConfig);
+      if (size > 0) {
+        button.setMinHeight((int) size);
+      }
+    }
+  }
+
   private void updateButtonTypeFaceWithPartnerConfig(
-      Button button, PartnerConfig buttonTextTypeFaceConfig) {
+      Button button, PartnerConfig buttonTextTypeFaceConfig, PartnerConfig buttonTextStyleConfig) {
     String fontFamilyName =
         PartnerConfigHelper.get(context).getString(context, buttonTextTypeFaceConfig);
-    Typeface font = Typeface.create(fontFamilyName, Typeface.NORMAL);
+
+    int textStyleValue = Typeface.NORMAL;
+    if (PartnerConfigHelper.get(context).isPartnerConfigAvailable(buttonTextStyleConfig)) {
+      textStyleValue =
+          PartnerConfigHelper.get(context)
+              .getInteger(context, buttonTextStyleConfig, Typeface.NORMAL);
+    }
+    Typeface font = Typeface.create(fontFamilyName, textStyleValue);
     if (font != null) {
       button.setTypeface(font);
     }
diff --git a/main/java/com/google/android/setupcompat/template/FooterButton.java b/main/java/com/google/android/setupcompat/template/FooterButton.java
index 2fa8c7c..b23b1bb 100644
--- a/main/java/com/google/android/setupcompat/template/FooterButton.java
+++ b/main/java/com/google/android/setupcompat/template/FooterButton.java
@@ -23,14 +23,14 @@
 import android.content.res.TypedArray;
 import android.os.Build.VERSION_CODES;
 import android.os.PersistableBundle;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.View.OnClickListener;
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
 import androidx.annotation.StyleRes;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.View.OnClickListener;
 import com.google.android.setupcompat.R;
 import com.google.android.setupcompat.logging.CustomEvent;
 import java.lang.annotation.Retention;
diff --git a/main/java/com/google/android/setupcompat/template/FooterButtonInflater.java b/main/java/com/google/android/setupcompat/template/FooterButtonInflater.java
index fe2538b..10aa052 100644
--- a/main/java/com/google/android/setupcompat/template/FooterButtonInflater.java
+++ b/main/java/com/google/android/setupcompat/template/FooterButtonInflater.java
@@ -19,10 +19,10 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
-import androidx.annotation.NonNull;
 import android.util.AttributeSet;
 import android.util.Xml;
 import android.view.InflateException;
+import androidx.annotation.NonNull;
 import java.io.IOException;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/main/java/com/google/android/setupcompat/template/StatusBarMixin.java b/main/java/com/google/android/setupcompat/template/StatusBarMixin.java
index 1bd6949..a818793 100644
--- a/main/java/com/google/android/setupcompat/template/StatusBarMixin.java
+++ b/main/java/com/google/android/setupcompat/template/StatusBarMixin.java
@@ -25,13 +25,13 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Build.VERSION_CODES;
-import androidx.annotation.AttrRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.Window;
 import android.widget.LinearLayout;
+import androidx.annotation.AttrRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import com.google.android.setupcompat.PartnerCustomizationLayout;
 import com.google.android.setupcompat.R;
 import com.google.android.setupcompat.partnerconfig.PartnerConfig;
diff --git a/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java b/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java
index e055d28..8050406 100644
--- a/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java
+++ b/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java
@@ -24,13 +24,13 @@
 import android.os.Build;
 import android.os.Build.VERSION;
 import android.os.Build.VERSION_CODES;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.Window;
 import androidx.annotation.AttrRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.Window;
 import com.google.android.setupcompat.PartnerCustomizationLayout;
 import com.google.android.setupcompat.R;
 import com.google.android.setupcompat.internal.TemplateLayout;
@@ -83,6 +83,19 @@
       setLightSystemNavBar(
           a.getBoolean(
               R.styleable.SucSystemNavBarMixin_sucLightSystemNavBar, isLightSystemNavBar()));
+
+      // Support updating system navigation bar divider color from P.
+      if (VERSION.SDK_INT >= VERSION_CODES.P) {
+        // get fallback value from theme
+        int[] navBarDividerColorAttr = new int[] {android.R.attr.navigationBarDividerColor};
+        TypedArray typedArray =
+            templateLayout.getContext().obtainStyledAttributes(navBarDividerColorAttr);
+        int defaultColor = typedArray.getColor(/* index= */ 0, /* defValue= */ 0);
+        int sucSystemNavBarDividerColor =
+            a.getColor(R.styleable.SucSystemNavBarMixin_sucSystemNavBarDividerColor, defaultColor);
+        setSystemNavBarDividerColor(sucSystemNavBarDividerColor);
+        typedArray.recycle();
+      }
       a.recycle();
     }
   }
@@ -120,6 +133,7 @@
    *
    * @param isLight true means compatible with light theme, otherwise compatible with dark theme
    */
+
   public void setLightSystemNavBar(boolean isLight) {
     if (Build.VERSION.SDK_INT >= VERSION_CODES.O && windowOfActivity != null) {
       if (applyPartnerResources) {
@@ -158,6 +172,28 @@
   }
 
   /**
+   * Sets the divider color of navigation bar. The color will be overridden by partner resource if
+   * the activity is running in setup wizard flow.
+   *
+   * @param color the default divider color of navigation bar
+   */
+  public void setSystemNavBarDividerColor(int color) {
+    if (Build.VERSION.SDK_INT >= VERSION_CODES.P && windowOfActivity != null) {
+      if (applyPartnerResources) {
+        Context context = templateLayout.getContext();
+        // Do nothing if the old version partner provider did not contain the new config.
+        if (PartnerConfigHelper.get(context)
+            .isPartnerConfigAvailable(PartnerConfig.CONFIG_NAVIGATION_BAR_DIVIDER_COLOR)) {
+          color =
+              PartnerConfigHelper.get(context)
+                  .getColor(context, PartnerConfig.CONFIG_NAVIGATION_BAR_DIVIDER_COLOR);
+        }
+      }
+      windowOfActivity.setNavigationBarDividerColor(color);
+    }
+  }
+
+  /**
    * Hides the navigation bar, make the color of the status and navigation bars transparent, and
    * specify {@link View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} flag so that the content is laid-out
    * behind the transparent status bar. This is commonly used with {@link
diff --git a/main/java/com/google/android/setupcompat/util/SystemBarHelper.java b/main/java/com/google/android/setupcompat/util/SystemBarHelper.java
index 75e5dd3..d61ff8b 100644
--- a/main/java/com/google/android/setupcompat/util/SystemBarHelper.java
+++ b/main/java/com/google/android/setupcompat/util/SystemBarHelper.java
@@ -24,13 +24,13 @@
 import android.os.Build.VERSION;
 import android.os.Build.VERSION_CODES;
 import android.os.Handler;
-import androidx.annotation.RequiresPermission;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowInsets;
 import android.view.WindowManager;
+import androidx.annotation.RequiresPermission;
 
 /**
  * A helper class to manage the system navigation bar and status bar. This will add various
diff --git a/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java b/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java
index bfe1dbb..79976bc 100644
--- a/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java
+++ b/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java
@@ -34,7 +34,7 @@
  */
 public final class WizardManagerHelper {
 
-  private static final String ACTION_NEXT = "com.android.wizard.NEXT";
+  @VisibleForTesting public static final String ACTION_NEXT = "com.android.wizard.NEXT";
 
   // EXTRA_SCRIPT_URI and EXTRA_ACTION_ID are used in setup wizard in versions before M and are
   // kept for backwards compatibility.
@@ -43,10 +43,27 @@
 
   @VisibleForTesting static final String EXTRA_WIZARD_BUNDLE = "wizardBundle";
   private static final String EXTRA_RESULT_CODE = "com.android.setupwizard.ResultCode";
-  @VisibleForTesting public static final String EXTRA_IS_FIRST_RUN = "firstRun";
-  @VisibleForTesting static final String EXTRA_IS_DEFERRED_SETUP = "deferredSetup";
-  @VisibleForTesting static final String EXTRA_IS_PRE_DEFERRED_SETUP = "preDeferredSetup";
-  @VisibleForTesting public static final String EXTRA_IS_SETUP_FLOW = "isSetupFlow";
+
+  /** Extra for notifying an Activity that it is inside the first SetupWizard flow or not. */
+  public static final String EXTRA_IS_FIRST_RUN = "firstRun";
+
+  /** Extra for notifying an Activity that it is inside the Deferred SetupWizard flow or not. */
+  public static final String EXTRA_IS_DEFERRED_SETUP = "deferredSetup";
+
+  /** Extra for notifying an Activity that it is inside the "Pre-Deferred Setup" flow. */
+  public static final String EXTRA_IS_PRE_DEFERRED_SETUP = "preDeferredSetup";
+
+  /** Extra for notifying an Activity that it is inside the "Portal Setup" flow. */
+  public static final String EXTRA_IS_PORTAL_SETUP = "portalSetup";
+
+  /**
+   * Extra for notifying an Activity that it is inside the any setup flow.
+   *
+   * <p>Apps that target API levels below {@link android.os.Build.VERSION_CODES#Q} is able to
+   * determine whether Activity is inside the any setup flow by one of {@link #EXTRA_IS_FIRST_RUN},
+   * {@link #EXTRA_IS_DEFERRED_SETUP}, and {@link #EXTRA_IS_PRE_DEFERRED_SETUP} is true.
+   */
+  public static final String EXTRA_IS_SETUP_FLOW = "isSetupFlow";
 
   public static final String EXTRA_THEME = "theme";
   public static final String EXTRA_USE_IMMERSIVE_MODE = "useImmersiveMode";
@@ -104,6 +121,7 @@
             EXTRA_IS_FIRST_RUN,
             EXTRA_IS_DEFERRED_SETUP,
             EXTRA_IS_PRE_DEFERRED_SETUP,
+            EXTRA_IS_PORTAL_SETUP,
             EXTRA_IS_SETUP_FLOW)) {
       dstIntent.putExtra(key, srcIntent.getBooleanExtra(key, false));
     }
diff --git a/main/res/values/attrs.xml b/main/res/values/attrs.xml
index 1a5342c..585a28a 100644
--- a/main/res/values/attrs.xml
+++ b/main/res/values/attrs.xml
@@ -52,6 +52,10 @@
              "android:windowTranslucentNavigation" should be set to false. -->
         <attr name="sucSystemNavBarBackgroundColor" format="color" />
         <attr name="sucLightSystemNavBar" format="boolean" />
+        <!-- The color for the system navigation bar divider. For this to take effect,
+             "android:windowDrawsSystemBarBackgrounds" should be set to true and
+             "android:windowTranslucentNavigation" should be set to false. -->
+        <attr name="sucSystemNavBarDividerColor" format="color" />
     </declare-styleable>
 
     <!-- FooterButton attributes -->
@@ -70,6 +74,8 @@
             <enum name="skip" value="7" />
             <enum name="stop" value="8" />
         </attr>
+        <attr name="sucFooterButtonPaddingStart" format="dimension" />
+        <attr name="sucFooterButtonPaddingEnd" format="dimension" />
     </declare-styleable>
 
     <!-- Button of footer attributes -->
@@ -87,11 +93,18 @@
         <attr name="sucFooterBarButtonColorControlHighlight" format="color" />
         <attr name="sucFooterBarButtonColorControlHighlightRipple" format="color" />
         <attr name="sucFooterBarPaddingVertical" format="dimension" />
+        <attr name="sucFooterBarPaddingStart" format="dimension" />
+        <attr name="sucFooterBarPaddingEnd" format="dimension" />
+        <attr name="sucFooterBarMinHeight" format="dimension" />
     </declare-styleable>
 
     <declare-styleable name="SucHeaderMixin">
         <attr name="sucHeaderText" format="string" localization="suggested" />
         <attr name="sucHeaderTextColor" format="reference|color" />
+        <attr name="sucGlifHeaderMarginTop" format="dimension" />
+        <attr name="sucGlifHeaderMarginBottom" format="dimension" />
+        <attr name="sucGlifIconMarginTop" format="dimension" />
+        <attr name="sucHeaderContainerMarginBottom" format="dimension" />
     </declare-styleable>
 
 </resources>
diff --git a/main/res/values/dimens.xml b/main/res/values/dimens.xml
deleted file mode 100644
index ef3d98d..0000000
--- a/main/res/values/dimens.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2018 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.
--->
-
-<resources>
-
-    <!-- TODO: Remove default values from setup compat, use from theme -->
-    <!-- Footer button bar style padding attributes-->
-    <dimen name="suc_customization_footer_min_height">72dp</dimen>
-    <dimen name="suc_customization_button_margin_start">8dp</dimen>
-    <dimen name="suc_customization_button_margin_end">20dp</dimen>
-
-    <!-- Footer button style padding attributes -->
-    <dimen name="suc_customization_button_padding">16dp</dimen>
-
-</resources>
diff --git a/main/res/values/styles.xml b/main/res/values/styles.xml
index 48fcddf..6474426 100644
--- a/main/res/values/styles.xml
+++ b/main/res/values/styles.xml
@@ -27,14 +27,14 @@
         <item name="android:clipChildren">false</item>
         <item name="android:clipToPadding">false</item>
         <item name="android:gravity">center_vertical</item>
-        <item name="android:minHeight">@dimen/suc_customization_footer_min_height</item>
+        <item name="android:minHeight">?attr/sucFooterBarMinHeight</item>
         <item name="android:orientation">horizontal</item>
         <item name="android:paddingTop">?attr/sucFooterBarPaddingVertical</item>
         <item name="android:paddingBottom">?attr/sucFooterBarPaddingVertical</item>
-        <item name="android:paddingEnd" tools:ignore="NewApi">@dimen/suc_customization_button_margin_end</item>
-        <item name="android:paddingLeft">@dimen/suc_customization_button_margin_start</item>
-        <item name="android:paddingRight">@dimen/suc_customization_button_margin_end</item>
-        <item name="android:paddingStart" tools:ignore="NewApi">@dimen/suc_customization_button_margin_start</item>
+        <item name="android:paddingEnd" tools:ignore="NewApi">?attr/sucFooterBarPaddingEnd</item>
+        <item name="android:paddingLeft">?attr/sucFooterBarPaddingStart</item>
+        <item name="android:paddingRight">?attr/sucFooterBarPaddingEnd</item>
+        <item name="android:paddingStart" tools:ignore="NewApi">?attr/sucFooterBarPaddingStart</item>
     </style>
 
     <style name="SucPartnerCustomizationButton.Primary" parent="android:Widget.Material.Button.Colored">
@@ -46,8 +46,10 @@
 
         <!-- Values used in styles -->
         <item name="android:fontFamily">?attr/sucFooterBarButtonFontFamily</item>
-        <item name="android:paddingLeft">@dimen/suc_customization_button_padding</item>
-        <item name="android:paddingRight">@dimen/suc_customization_button_padding</item>
+        <item name="android:paddingLeft">?attr/sucFooterButtonPaddingStart</item>
+        <item name="android:paddingStart" tools:ignore="NewApi">?attr/sucFooterButtonPaddingStart</item>
+        <item name="android:paddingRight">?attr/sucFooterButtonPaddingEnd</item>
+        <item name="android:paddingEnd" tools:ignore="NewApi">?attr/sucFooterButtonPaddingEnd</item>
         <item name="android:textAllCaps">?attr/sucFooterBarButtonAllCaps</item>
         <item name="android:stateListAnimator">@null</item>
 
@@ -65,8 +67,10 @@
         <!-- Values used in styles -->
         <item name="android:fontFamily">?attr/sucFooterBarButtonFontFamily</item>
         <item name="android:minWidth">0dp</item>
-        <item name="android:paddingLeft">@dimen/suc_customization_button_padding</item>
-        <item name="android:paddingRight">@dimen/suc_customization_button_padding</item>
+        <item name="android:paddingLeft">?attr/sucFooterButtonPaddingStart</item>
+        <item name="android:paddingStart" tools:ignore="NewApi">?attr/sucFooterButtonPaddingStart</item>
+        <item name="android:paddingRight">?attr/sucFooterButtonPaddingEnd</item>
+        <item name="android:paddingEnd" tools:ignore="NewApi">?attr/sucFooterButtonPaddingEnd</item>
         <item name="android:textAllCaps">?attr/sucFooterBarButtonAllCaps</item>
 
         <!-- Values used in themes -->
diff --git a/partnerconfig/AndroidManifest.xml b/partnerconfig/AndroidManifest.xml
index c95a4dd..43e2041 100644
--- a/partnerconfig/AndroidManifest.xml
+++ b/partnerconfig/AndroidManifest.xml
@@ -16,9 +16,16 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     package="com.google.android.setupcompat.partnerconfig">
 
-  <uses-sdk
-      android:minSdkVersion="14"
-      android:targetSdkVersion="28" />
+  <uses-sdk />
+
+  <!-- after SDK 30, package need to declare its visible packages. -->
+  <queries tools:node="merge">
+    <intent>
+      <action android:name="com.android.setupwizard.action.PARTNER_CUSTOMIZATION" />
+    </intent>
+    <provider android:authorities="com.google.android.setupwizard.partner" />
+  </queries>
 </manifest>
diff --git a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java
index 56256c9..5a71afe 100644
--- a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java
@@ -30,9 +30,16 @@
   // Navigation bar background color
   CONFIG_NAVIGATION_BAR_BG_COLOR(PartnerConfigKey.KEY_NAVIGATION_BAR_BG_COLOR, ResourceType.COLOR),
 
+  // Navigation bar divider color
+  CONFIG_NAVIGATION_BAR_DIVIDER_COLOR(
+      PartnerConfigKey.KEY_NAVIGATION_BAR_DIVIDER_COLOR, ResourceType.COLOR),
+
   // Background color of the footer bar.
   CONFIG_FOOTER_BAR_BG_COLOR(PartnerConfigKey.KEY_FOOTER_BAR_BG_COLOR, ResourceType.COLOR),
 
+  // The min height of the footer buttons
+  CONFIG_FOOTER_BAR_MIN_HEIGHT(PartnerConfigKey.KEY_FOOTER_BAR_MIN_HEIGHT, ResourceType.DIMENSION),
+
   // The same as "windowLightNavigationBar". If set true, the navigation bar icons will be drawn
   // such that it is compatible with a light navigation bar background.
   CONFIG_LIGHT_NAVIGATION_BAR(PartnerConfigKey.KEY_LIGHT_NAVIGATION_BAR, ResourceType.BOOL),
@@ -89,10 +96,18 @@
   CONFIG_FOOTER_BUTTON_RIPPLE_COLOR_ALPHA(
       PartnerConfigKey.KEY_FOOTER_BUTTON_RIPPLE_ALPHA, ResourceType.FRACTION),
 
-  // Text size of the primary footer button
+  // Text size of the footer buttons
   CONFIG_FOOTER_BUTTON_TEXT_SIZE(
       PartnerConfigKey.KEY_FOOTER_BUTTON_TEXT_SIZE, ResourceType.DIMENSION),
 
+  // The text style of footer buttons {0 = NORMAL}, {1 = BOLD}, {2 = ITALIC}, {3 = BOLD_ITALIC}
+  CONFIG_FOOTER_BUTTON_TEXT_STYLE(
+      PartnerConfigKey.KEY_FOOTER_BUTTON_TEXT_STYLE, ResourceType.INTEGER),
+
+  // The min height of the footer buttons
+  CONFIG_FOOTER_BUTTON_MIN_HEIGHT(
+      PartnerConfigKey.KEY_FOOTER_BUTTON_MIN_HEIGHT, ResourceType.DIMENSION),
+
   // Disabled background alpha of the footer buttons
   CONFIG_FOOTER_BUTTON_DISABLED_ALPHA(
       PartnerConfigKey.KEY_FOOTER_BUTTON_DISABLED_ALPHA, ResourceType.FRACTION),
@@ -120,6 +135,12 @@
   // Background color of layout
   CONFIG_LAYOUT_BACKGROUND_COLOR(PartnerConfigKey.KEY_LAYOUT_BACKGROUND_COLOR, ResourceType.COLOR),
 
+  // Margin start of the layout
+  CONFIG_LAYOUT_MARGIN_START(PartnerConfigKey.KEY_LAYOUT_MARGIN_START, ResourceType.DIMENSION),
+
+  // Margin end of the layout
+  CONFIG_LAYOUT_MARGIN_END(PartnerConfigKey.KEY_LAYOUT_MARGIN_END, ResourceType.DIMENSION),
+
   // Text color of the header
   CONFIG_HEADER_TEXT_COLOR(PartnerConfigKey.KEY_HEADER_TEXT_COLOR, ResourceType.COLOR),
 
@@ -129,13 +150,50 @@
   // Font family of the header
   CONFIG_HEADER_FONT_FAMILY(PartnerConfigKey.KEY_HEADER_FONT_FAMILY, ResourceType.STRING),
 
+  // Margin top of the header text
+  CONFIG_HEADER_TEXT_MARGIN_TOP(
+      PartnerConfigKey.KEY_HEADER_TEXT_MARGIN_TOP, ResourceType.DIMENSION),
+
+  // Margin bottom of the header text
+  CONFIG_HEADER_TEXT_MARGIN_BOTTOM(
+      PartnerConfigKey.KEY_HEADER_TEXT_MARGIN_BOTTOM, ResourceType.DIMENSION),
+
   // Gravity of the header, icon and description
   CONFIG_LAYOUT_GRAVITY(PartnerConfigKey.KEY_LAYOUT_GRAVITY, ResourceType.STRING),
 
+  // Margin top of the icon
+  CONFIG_ICON_MARGIN_TOP(PartnerConfigKey.KEY_ICON_MARGIN_TOP, ResourceType.DIMENSION),
+
+  // Size of the icon
+  CONFIG_ICON_SIZE(PartnerConfigKey.KEY_ICON_SIZE, ResourceType.DIMENSION),
+
   // Background color of the header area
   CONFIG_HEADER_AREA_BACKGROUND_COLOR(
       PartnerConfigKey.KEY_HEADER_AREA_BACKGROUND_COLOR, ResourceType.COLOR),
 
+  // Margin bottom of the header container
+  CONFIG_HEADER_CONTAINER_MARGIN_BOTTOM(
+      PartnerConfigKey.KEY_HEADER_CONTAINER_MARGIN_BOTTOM, ResourceType.DIMENSION),
+
+  // Auto text size enabled status
+  CONFIG_HEADER_AUTO_SIZE_ENABLED(PartnerConfigKey.KEY_HEADER_AUTO_SIZE_ENABLED, ResourceType.BOOL),
+
+  // Max text size of header when auto size enabled. Ignored if auto size is false.
+  CONFIG_HEADER_AUTO_SIZE_MAX_TEXT_SIZE(
+      PartnerConfigKey.KEY_HEADER_AUTO_SIZE_MAX_TEXT_SIZE, ResourceType.DIMENSION),
+
+  // Min text size of header when auto size enabled. Ignored if auto size is false.
+  CONFIG_HEADER_AUTO_SIZE_MIN_TEXT_SIZE(
+      PartnerConfigKey.KEY_HEADER_AUTO_SIZE_MIN_TEXT_SIZE, ResourceType.DIMENSION),
+
+  // The max lines of the max text size when auto size enabled. Ignored if auto size is false.
+  CONFIG_HEADER_AUTO_SIZE_MAX_LINE_OF_MAX_SIZE(
+      PartnerConfigKey.KEY_HEADER_AUTO_SIZE_MAX_LINE_OF_MAX_SIZE, ResourceType.INTEGER),
+
+  // Extra line spacing of header when auto size enabled. Ignored if auto size is false.
+  CONFIG_HEADER_AUTO_SIZE_LINE_SPACING_EXTRA(
+      PartnerConfigKey.KEY_HEADER_AUTO_SIZE_LINE_SPACING_EXTRA, ResourceType.DIMENSION),
+
   // Text size of the description
   CONFIG_DESCRIPTION_TEXT_SIZE(PartnerConfigKey.KEY_DESCRIPTION_TEXT_SIZE, ResourceType.DIMENSION),
 
@@ -149,6 +207,14 @@
   // Font family of the description
   CONFIG_DESCRIPTION_FONT_FAMILY(PartnerConfigKey.KEY_DESCRIPTION_FONT_FAMILY, ResourceType.STRING),
 
+  // Margin top of the description text
+  CONFIG_DESCRIPTION_TEXT_MARGIN_TOP(
+      PartnerConfigKey.KEY_DESCRIPTION_TEXT_MARGIN_TOP, ResourceType.DIMENSION),
+
+  // Margin bottom of the description text
+  CONFIG_DESCRIPTION_TEXT_MARGIN_BOTTOM(
+      PartnerConfigKey.KEY_DESCRIPTION_TEXT_MARGIN_BOTTOM, ResourceType.DIMENSION),
+
   // Text size of the body content text
   CONFIG_CONTENT_TEXT_SIZE(PartnerConfigKey.KEY_CONTENT_TEXT_SIZE, ResourceType.DIMENSION),
 
@@ -164,6 +230,39 @@
   // Gravity of the body content text
   CONFIG_CONTENT_LAYOUT_GRAVITY(PartnerConfigKey.KEY_CONTENT_LAYOUT_GRAVITY, ResourceType.STRING),
 
+  // The padding top of the content
+  CONFIG_CONTENT_PADDING_TOP(PartnerConfigKey.KEY_CONTENT_PADDING_TOP, ResourceType.DIMENSION),
+
+  // The title text size of list items.
+  CONFIG_ITEMS_TITLE_TEXT_SIZE(PartnerConfigKey.KEY_ITEMS_TITLE_TEXT_SIZE, ResourceType.DIMENSION),
+
+  // The summary text size of list items.
+  CONFIG_ITEMS_SUMMARY_TEXT_SIZE(
+      PartnerConfigKey.KEY_ITEMS_SUMMARY_TEXT_SIZE, ResourceType.DIMENSION),
+
+  // The summary margin top of list items.
+  CONFIG_ITEMS_SUMMARY_MARGIN_TOP(
+      PartnerConfigKey.KEY_ITEMS_SUMMARY_MARGIN_TOP, ResourceType.DIMENSION),
+
+  // The title font family of list items.
+  CONFIG_ITEMS_TITLE_FONT_FAMILY(PartnerConfigKey.KEY_ITEMS_TITLE_FONT_FAMILY, ResourceType.STRING),
+
+  // The summary font family of list items.
+  CONFIG_ITEMS_SUMMARY_FONT_FAMILY(
+      PartnerConfigKey.KEY_ITEMS_SUMMARY_FONT_FAMILY, ResourceType.STRING),
+
+  // The padding top of list items.
+  CONFIG_ITEMS_PADDING_TOP(PartnerConfigKey.KEY_ITEMS_PADDING_TOP, ResourceType.DIMENSION),
+
+  // The padding bottom of list items.
+  CONFIG_ITEMS_PADDING_BOTTOM(PartnerConfigKey.KEY_ITEMS_PADDING_BOTTOM, ResourceType.DIMENSION),
+
+  // The minimum height of list items.
+  CONFIG_ITEMS_MIN_HEIGHT(PartnerConfigKey.KEY_ITEMS_MIN_HEIGHT, ResourceType.DIMENSION),
+
+  // The divider of list items are showing on the pages.
+  CONFIG_ITEMS_DIVIDER_SHOWN(PartnerConfigKey.KEY_ITEMS_DIVIDER_SHOWN, ResourceType.BOOL),
+
   // The animation of loading screen used in those activities which is non of below type.
   CONFIG_PROGRESS_ILLUSTRATION_DEFAULT(
       PartnerConfigKey.KEY_PROGRESS_ILLUSTRATION_DEFAULT, ResourceType.ILLUSTRATION),
@@ -184,9 +283,66 @@
   CONFIG_PROGRESS_ILLUSTRATION_UPDATE(
       PartnerConfigKey.KEY_PROGRESS_ILLUSTRATION_UPDATE, ResourceType.ILLUSTRATION),
 
+  // The animation of loading screen to define how long showing on the pages.
   CONFIG_PROGRESS_ILLUSTRATION_DISPLAY_MINIMUM_MS(
-      PartnerConfigKey.KEY_PROGRESS_ILLUSTRATION_DISPLAY_MINIMUM_MS, ResourceType.INTEGER);
+      PartnerConfigKey.KEY_PROGRESS_ILLUSTRATION_DISPLAY_MINIMUM_MS, ResourceType.INTEGER),
 
+  // The animation for S+ devices used in those screens waiting for non of below type.
+  CONFIG_LOADING_LOTTIE_DEFAULT(
+      PartnerConfigKey.KEY_LOADING_LOTTIE_DEFAULT, ResourceType.ILLUSTRATION),
+
+  // The animation for S+ devices used in those screens which is processing account info or related
+  // functions.
+  // For example:com.google.android.setupwizard.LOAD_ADD_ACCOUNT_INTENT
+  CONFIG_LOADING_LOTTIE_ACCOUNT(
+      PartnerConfigKey.KEY_LOADING_LOTTIE_ACCOUNT, ResourceType.ILLUSTRATION),
+
+  // The animation for S+ devices used in those screens which is processing data connection.
+  // For example:com.android.setupwizard.CAPTIVE_PORTAL
+  CONFIG_LOADING_LOTTIE_CONNECTION(
+      PartnerConfigKey.KEY_LOADING_LOTTIE_CONNECTION, ResourceType.ILLUSTRATION),
+
+  // The animation for S+ devices used in those screens which is updating devices.
+  // For example:com.google.android.setupwizard.COMPAT_EARLY_UPDATE
+  CONFIG_LOADING_LOTTIE_UPDATE(
+      PartnerConfigKey.KEY_LOADING_LOTTIE_UPDATE, ResourceType.ILLUSTRATION),
+
+  // The transition type to decide the transition between activities or fragments.
+  CONFIG_TRANSITION_TYPE(PartnerConfigKey.KEY_TRANSITION_TYPE, ResourceType.INTEGER),
+
+  // The list of keypath and color map, applied to default animation when light theme.
+  CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_DEFAULT(
+      PartnerConfigKey.KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_DEFAULT, ResourceType.STRING_ARRAY),
+
+  // The list of keypath and color map, applied to account animation when light theme.
+  CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_ACCOUNT(
+      PartnerConfigKey.KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_ACCOUNT, ResourceType.STRING_ARRAY),
+
+  // The list of keypath and color map, applied to connection animation when light theme.
+  CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_CONNECTION(
+      PartnerConfigKey.KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_CONNECTION, ResourceType.STRING_ARRAY),
+
+  // The list of keypath and color map, applied to update animation when light theme.
+  CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_UPDATE(
+      PartnerConfigKey.KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_UPDATE, ResourceType.STRING_ARRAY),
+
+  // The list of keypath and color map, applied to default animation when dark theme.
+  CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_DEFAULT(
+      PartnerConfigKey.KEY_LOADING_DARK_THEME_CUSTOMIZATION_DEFAULT, ResourceType.STRING_ARRAY),
+
+  // The list of keypath and color map, applied to account animation when dark theme.
+  CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_ACCOUNT(
+      PartnerConfigKey.KEY_LOADING_DARK_THEME_CUSTOMIZATION_ACCOUNT, ResourceType.STRING_ARRAY),
+
+  // The list of keypath and color map, applied to connection animation when dark theme.
+  CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_CONNECTION(
+      PartnerConfigKey.KEY_LOADING_DARK_THEME_CUSTOMIZATION_CONNECTION, ResourceType.STRING_ARRAY),
+
+  // The list of keypath and color map, applied to update animation when dark theme.
+  CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_UPDATE(
+      PartnerConfigKey.KEY_LOADING_DARK_THEME_CUSTOMIZATION_UPDATE, ResourceType.STRING_ARRAY);
+
+  /** Resource type of the partner resources type. */
   public enum ResourceType {
     INTEGER,
     BOOL,
@@ -195,7 +351,8 @@
     STRING,
     DIMENSION,
     FRACTION,
-    ILLUSTRATION;
+    ILLUSTRATION,
+    STRING_ARRAY
   }
 
   private final String resourceName;
diff --git a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java
index 7b9f65b..f53ee40 100644
--- a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java
@@ -1,11 +1,11 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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
+ *      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,
@@ -18,22 +18,27 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
+import android.database.ContentObserver;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.TypedValue;
 import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.TypedValue;
 import com.google.android.setupcompat.partnerconfig.PartnerConfig.ResourceType;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.EnumMap;
+import java.util.List;
 
 /** The helper reads and caches the partner configurations from SUW. */
 public class PartnerConfigHelper {
@@ -47,6 +52,22 @@
 
   @VisibleForTesting public static final String KEY_FALLBACK_CONFIG = "fallbackConfig";
 
+  @VisibleForTesting
+  public static final String IS_SUW_DAY_NIGHT_ENABLED_METHOD = "isSuwDayNightEnabled";
+
+  @VisibleForTesting
+  public static final String IS_EXTENDED_PARTNER_CONFIG_ENABLED_METHOD =
+      "isExtendedPartnerConfigEnabled";
+
+  @VisibleForTesting
+  public static final String IS_DYNAMIC_COLOR_ENABLED_METHOD = "isDynamicColorEnabled";
+
+  @VisibleForTesting static Bundle suwDayNightEnabledBundle = null;
+
+  @VisibleForTesting public static Bundle applyExtendedPartnerConfigBundle = null;
+
+  @VisibleForTesting static Bundle applyDynamicColorBundle = null;
+
   private static PartnerConfigHelper instance = null;
 
   @VisibleForTesting Bundle resultBundle = null;
@@ -54,15 +75,44 @@
   @VisibleForTesting
   final EnumMap<PartnerConfig, Object> partnerResourceCache = new EnumMap<>(PartnerConfig.class);
 
+  private static ContentObserver contentObserver;
+
+  private static int savedConfigUiMode;
+
+  private static int savedOrientation = Configuration.ORIENTATION_PORTRAIT;
+
   public static synchronized PartnerConfigHelper get(@NonNull Context context) {
-    if (instance == null) {
+    if (!isValidInstance(context)) {
       instance = new PartnerConfigHelper(context);
     }
     return instance;
   }
 
+  private static boolean isValidInstance(@NonNull Context context) {
+    Configuration currentConfig = context.getResources().getConfiguration();
+    if (instance == null) {
+      savedConfigUiMode = currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
+      savedOrientation = currentConfig.orientation;
+      return false;
+    } else {
+      if (isSetupWizardDayNightEnabled(context)
+          && (currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) != savedConfigUiMode) {
+        savedConfigUiMode = currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
+        resetInstance();
+        return false;
+      } else if (currentConfig.orientation != savedOrientation) {
+        savedOrientation = currentConfig.orientation;
+        resetInstance();
+        return false;
+      }
+    }
+    return true;
+  }
+
   private PartnerConfigHelper(Context context) {
     getPartnerConfigBundle(context);
+
+    registerContentObserver(context);
   }
 
   /**
@@ -75,12 +125,22 @@
   }
 
   /**
+   * Returns whether the given {@code resourceConfig} are available. This is true if setup wizard's
+   * content provider returns us a non-empty bundle, and this result bundle includes the given
+   * {@code resourceConfig} even if all the values are default, and none are customized by the
+   * overlay APK.
+   */
+  public boolean isPartnerConfigAvailable(PartnerConfig resourceConfig) {
+    return isAvailable() && resultBundle.containsKey(resourceConfig.getResourceName());
+  }
+
+  /**
    * Returns the color of given {@code resourceConfig}, or 0 if the given {@code resourceConfig} is
    * not found. If the {@code ResourceType} of the given {@code resourceConfig} is not color,
    * IllegalArgumentException will be thrown.
    *
    * @param context The context of client activity
-   * @param resourceConfig The {@code PartnerConfig} of target resource
+   * @param resourceConfig The {@link PartnerConfig} of target resource
    */
   @ColorInt
   public int getColor(@NonNull Context context, PartnerConfig resourceConfig) {
@@ -189,6 +249,38 @@
   }
 
   /**
+   * Returns the string array of the given {@code resourceConfig}, or {@code null} if the given
+   * {@code resourceConfig} is not found. If the {@code ResourceType} of the given {@code
+   * resourceConfig} is not string, IllegalArgumentException will be thrown.
+   *
+   * @param context The context of client activity
+   * @param resourceConfig The {@code PartnerConfig} of target resource
+   */
+  @NonNull
+  public List<String> getStringArray(@NonNull Context context, PartnerConfig resourceConfig) {
+    if (resourceConfig.getResourceType() != ResourceType.STRING_ARRAY) {
+      throw new IllegalArgumentException("Not a string array resource");
+    }
+
+    String[] result;
+    List<String> listResult = new ArrayList<>();
+
+    try {
+      ResourceEntry resourceEntry =
+          getResourceEntryFromKey(context, resourceConfig.getResourceName());
+      Resources resource = resourceEntry.getResources();
+      int resId = resourceEntry.getResourceId();
+
+      result = resource.getStringArray(resId);
+      Collections.addAll(listResult, result);
+    } catch (NullPointerException exception) {
+      // fall through
+    }
+
+    return listResult;
+  }
+
+  /**
    * Returns the boolean of given {@code resourceConfig}, or {@code defaultValue} if the given
    * {@code resourceName} is not found. If the {@code ResourceType} of the given {@code
    * resourceConfig} is not boolean, IllegalArgumentException will be thrown.
@@ -233,8 +325,8 @@
   }
 
   /**
-   * Returns the dimension of given {@code resourceConfig}. If the given {@code resourceConfig} not
-   * found, will return {@code defaultValue}. If the {@code ResourceType} of given {@code
+   * Returns the dimension of given {@code resourceConfig}. If the given {@code resourceConfig} is
+   * not found, will return {@code defaultValue}. If the {@code ResourceType} of given {@code
    * resourceConfig} is not dimension, will throw IllegalArgumentException.
    *
    * @param context The context of client activity
@@ -316,6 +408,39 @@
   }
 
   /**
+   * Returns the integer of given {@code resourceConfig}. If the given {@code resourceConfig} is not
+   * found, will return {@code defaultValue}. If the {@code ResourceType} of given {@code
+   * resourceConfig} is not dimension, will throw IllegalArgumentException.
+   *
+   * @param context The context of client activity
+   * @param resourceConfig The {@code PartnerConfig} of target resource
+   * @param defaultValue The default value
+   */
+  public int getInteger(@NonNull Context context, PartnerConfig resourceConfig, int defaultValue) {
+    if (resourceConfig.getResourceType() != ResourceType.INTEGER) {
+      throw new IllegalArgumentException("Not a integer resource");
+    }
+
+    if (partnerResourceCache.containsKey(resourceConfig)) {
+      return (int) partnerResourceCache.get(resourceConfig);
+    }
+
+    int result = defaultValue;
+    try {
+      ResourceEntry resourceEntry =
+          getResourceEntryFromKey(context, resourceConfig.getResourceName());
+      Resources resource = resourceEntry.getResources();
+      int resId = resourceEntry.getResourceId();
+
+      result = resource.getInteger(resId);
+      partnerResourceCache.put(resourceConfig, result);
+    } catch (NullPointerException exception) {
+      // fall through
+    }
+    return result;
+  }
+
+  /**
    * Returns the {@link ResourceEntry} of given {@code resourceConfig}, or {@code null} if the given
    * {@code resourceConfig} is not found. If the {@link ResourceType} of the given {@code
    * resourceConfig} is not illustration, IllegalArgumentException will be thrown.
@@ -362,17 +487,14 @@
   private void getPartnerConfigBundle(Context context) {
     if (resultBundle == null || resultBundle.isEmpty()) {
       try {
-        Uri contentUri =
-            new Uri.Builder()
-                .scheme(ContentResolver.SCHEME_CONTENT)
-                .authority(SUW_AUTHORITY)
-                .appendPath(SUW_GET_PARTNER_CONFIG_METHOD)
-                .build();
         resultBundle =
             context
                 .getContentResolver()
                 .call(
-                    contentUri, SUW_GET_PARTNER_CONFIG_METHOD, /* arg= */ null, /* extras= */ null);
+                    getContentUri(),
+                    SUW_GET_PARTNER_CONFIG_METHOD,
+                    /* arg= */ null,
+                    /* extras= */ null);
         partnerResourceCache.clear();
       } catch (IllegalArgumentException | SecurityException exception) {
         Log.w(TAG, "Fail to get config from suw provider");
@@ -381,21 +503,134 @@
   }
 
   @Nullable
-  private ResourceEntry getResourceEntryFromKey(Context context, String resourceName) {
+  @VisibleForTesting
+  ResourceEntry getResourceEntryFromKey(Context context, String resourceName) {
     Bundle resourceEntryBundle = resultBundle.getBundle(resourceName);
     Bundle fallbackBundle = resultBundle.getBundle(KEY_FALLBACK_CONFIG);
     if (fallbackBundle != null) {
       resourceEntryBundle.putBundle(KEY_FALLBACK_CONFIG, fallbackBundle.getBundle(resourceName));
     }
-    return ResourceEntry.fromBundle(context, resourceEntryBundle);
+
+    return adjustResourceEntryDayNightMode(
+        context, ResourceEntry.fromBundle(context, resourceEntryBundle));
+  }
+
+  /**
+   * Force to day mode if setup wizard does not support day/night mode and current system is in
+   * night mode.
+   */
+  private static ResourceEntry adjustResourceEntryDayNightMode(
+      Context context, ResourceEntry resourceEntry) {
+    Resources resource = resourceEntry.getResources();
+    Configuration configuration = resource.getConfiguration();
+    if (!isSetupWizardDayNightEnabled(context) && Util.isNightMode(configuration)) {
+      if (resourceEntry == null) {
+        Log.w(TAG, "resourceEntry is null, skip to force day mode.");
+        return resourceEntry;
+      }
+      configuration.uiMode =
+          Configuration.UI_MODE_NIGHT_NO
+              | (configuration.uiMode & ~Configuration.UI_MODE_NIGHT_MASK);
+      resource.updateConfiguration(configuration, resource.getDisplayMetrics());
+    }
+
+    return resourceEntry;
   }
 
   @VisibleForTesting
-  public static synchronized void resetForTesting() {
+  public static synchronized void resetInstance() {
     instance = null;
+    suwDayNightEnabledBundle = null;
+    applyExtendedPartnerConfigBundle = null;
+    applyDynamicColorBundle = null;
   }
 
-  private TypedValue getTypedValueFromResource(Resources resource, int resId, int type) {
+  /**
+   * Checks whether SetupWizard supports the DayNight theme during setup flow; if return false setup
+   * flow should force to light theme.
+   *
+   * <p>Returns true if the setupwizard is listening to system DayNight theme setting.
+   */
+  public static boolean isSetupWizardDayNightEnabled(@NonNull Context context) {
+    if (suwDayNightEnabledBundle == null) {
+      try {
+        suwDayNightEnabledBundle =
+            context
+                .getContentResolver()
+                .call(
+                    getContentUri(),
+                    IS_SUW_DAY_NIGHT_ENABLED_METHOD,
+                    /* arg= */ null,
+                    /* extras= */ null);
+      } catch (IllegalArgumentException | SecurityException exception) {
+        Log.w(TAG, "SetupWizard DayNight supporting status unknown; return as false.");
+        suwDayNightEnabledBundle = null;
+        return false;
+      }
+    }
+
+    return (suwDayNightEnabledBundle != null
+        && suwDayNightEnabledBundle.getBoolean(IS_SUW_DAY_NIGHT_ENABLED_METHOD, false));
+  }
+
+  /** Returns true if the SetupWizard supports the extended partner configs during setup flow. */
+  public static boolean shouldApplyExtendedPartnerConfig(@NonNull Context context) {
+    if (applyExtendedPartnerConfigBundle == null) {
+      try {
+        applyExtendedPartnerConfigBundle =
+            context
+                .getContentResolver()
+                .call(
+                    getContentUri(),
+                    IS_EXTENDED_PARTNER_CONFIG_ENABLED_METHOD,
+                    /* arg= */ null,
+                    /* extras= */ null);
+      } catch (IllegalArgumentException | SecurityException exception) {
+        Log.w(
+            TAG,
+            "SetupWizard extended partner configs supporting status unknown; return as false.");
+        applyExtendedPartnerConfigBundle = null;
+        return false;
+      }
+    }
+
+    return (applyExtendedPartnerConfigBundle != null
+        && applyExtendedPartnerConfigBundle.getBoolean(
+            IS_EXTENDED_PARTNER_CONFIG_ENABLED_METHOD, false));
+  }
+
+  /** Returns true if the SetupWizard supports the dynamic color during setup flow. */
+  public static boolean shouldApplyDynamicColor(@NonNull Context context) {
+    if (applyDynamicColorBundle == null) {
+      try {
+        applyDynamicColorBundle =
+            context
+                .getContentResolver()
+                .call(
+                    getContentUri(),
+                    IS_DYNAMIC_COLOR_ENABLED_METHOD,
+                    /* arg= */ null,
+                    /* extras= */ null);
+      } catch (IllegalArgumentException | SecurityException exception) {
+        Log.w(TAG, "SetupWizard dynamic color supporting status unknown; return as false.");
+        applyDynamicColorBundle = null;
+        return false;
+      }
+    }
+
+    return (applyDynamicColorBundle != null
+        && applyDynamicColorBundle.getBoolean(IS_DYNAMIC_COLOR_ENABLED_METHOD, false));
+  }
+
+  @VisibleForTesting
+  static Uri getContentUri() {
+    return new Uri.Builder()
+        .scheme(ContentResolver.SCHEME_CONTENT)
+        .authority(SUW_AUTHORITY)
+        .build();
+  }
+
+  private static TypedValue getTypedValueFromResource(Resources resource, int resId, int type) {
     TypedValue value = new TypedValue();
     resource.getValue(resId, value, true);
     if (value.type != type) {
@@ -409,8 +644,42 @@
     return value;
   }
 
-  private float getDimensionFromTypedValue(Context context, TypedValue value) {
+  private static float getDimensionFromTypedValue(Context context, TypedValue value) {
     DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
     return value.getDimension(displayMetrics);
   }
+
+  private static void registerContentObserver(Context context) {
+    if (isSetupWizardDayNightEnabled(context)) {
+      if (contentObserver != null) {
+        unregisterContentObserver(context);
+      }
+
+      Uri contentUri = getContentUri();
+      try {
+        contentObserver =
+            new ContentObserver(null) {
+              @Override
+              public void onChange(boolean selfChange) {
+                super.onChange(selfChange);
+                resetInstance();
+              }
+            };
+        context
+            .getContentResolver()
+            .registerContentObserver(contentUri, /* notifyForDescendants= */ true, contentObserver);
+      } catch (SecurityException | NullPointerException | IllegalArgumentException e) {
+        Log.w(TAG, "Failed to register content observer for " + contentUri + ": " + e);
+      }
+    }
+  }
+
+  private static void unregisterContentObserver(Context context) {
+    try {
+      context.getContentResolver().unregisterContentObserver(contentObserver);
+      contentObserver = null;
+    } catch (SecurityException | NullPointerException | IllegalArgumentException e) {
+      Log.w(TAG, "Failed to unregister content observer: " + e);
+    }
+  }
 }
diff --git a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java
index e5c5442..4f21ae2 100644
--- a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java
@@ -28,7 +28,9 @@
   PartnerConfigKey.KEY_LIGHT_STATUS_BAR,
   PartnerConfigKey.KEY_NAVIGATION_BAR_BG_COLOR,
   PartnerConfigKey.KEY_LIGHT_NAVIGATION_BAR,
+  PartnerConfigKey.KEY_NAVIGATION_BAR_DIVIDER_COLOR,
   PartnerConfigKey.KEY_FOOTER_BAR_BG_COLOR,
+  PartnerConfigKey.KEY_FOOTER_BAR_MIN_HEIGHT,
   PartnerConfigKey.KEY_FOOTER_BUTTON_FONT_FAMILY,
   PartnerConfigKey.KEY_FOOTER_BUTTON_ICON_ADD_ANOTHER,
   PartnerConfigKey.KEY_FOOTER_BUTTON_ICON_CANCEL,
@@ -43,6 +45,8 @@
   PartnerConfigKey.KEY_FOOTER_BUTTON_RADIUS,
   PartnerConfigKey.KEY_FOOTER_BUTTON_RIPPLE_ALPHA,
   PartnerConfigKey.KEY_FOOTER_BUTTON_TEXT_SIZE,
+  PartnerConfigKey.KEY_FOOTER_BUTTON_TEXT_STYLE,
+  PartnerConfigKey.KEY_FOOTER_BUTTON_MIN_HEIGHT,
   PartnerConfigKey.KEY_FOOTER_BUTTON_DISABLED_ALPHA,
   PartnerConfigKey.KEY_FOOTER_BUTTON_DISABLED_BG_COLOR,
   PartnerConfigKey.KEY_FOOTER_PRIMARY_BUTTON_BG_COLOR,
@@ -50,25 +54,62 @@
   PartnerConfigKey.KEY_FOOTER_SECONDARY_BUTTON_BG_COLOR,
   PartnerConfigKey.KEY_FOOTER_SECONDARY_BUTTON_TEXT_COLOR,
   PartnerConfigKey.KEY_LAYOUT_BACKGROUND_COLOR,
+  PartnerConfigKey.KEY_LAYOUT_MARGIN_START,
+  PartnerConfigKey.KEY_LAYOUT_MARGIN_END,
   PartnerConfigKey.KEY_HEADER_TEXT_SIZE,
   PartnerConfigKey.KEY_HEADER_TEXT_COLOR,
   PartnerConfigKey.KEY_HEADER_FONT_FAMILY,
   PartnerConfigKey.KEY_HEADER_AREA_BACKGROUND_COLOR,
+  PartnerConfigKey.KEY_HEADER_TEXT_MARGIN_TOP,
+  PartnerConfigKey.KEY_HEADER_TEXT_MARGIN_BOTTOM,
+  PartnerConfigKey.KEY_HEADER_CONTAINER_MARGIN_BOTTOM,
+  PartnerConfigKey.KEY_HEADER_AUTO_SIZE_ENABLED,
+  PartnerConfigKey.KEY_HEADER_AUTO_SIZE_MAX_TEXT_SIZE,
+  PartnerConfigKey.KEY_HEADER_AUTO_SIZE_MIN_TEXT_SIZE,
+  PartnerConfigKey.KEY_HEADER_AUTO_SIZE_MAX_LINE_OF_MAX_SIZE,
+  PartnerConfigKey.KEY_HEADER_AUTO_SIZE_LINE_SPACING_EXTRA,
   PartnerConfigKey.KEY_LAYOUT_GRAVITY,
+  PartnerConfigKey.KEY_ICON_MARGIN_TOP,
+  PartnerConfigKey.KEY_ICON_SIZE,
   PartnerConfigKey.KEY_DESCRIPTION_TEXT_SIZE,
   PartnerConfigKey.KEY_DESCRIPTION_TEXT_COLOR,
   PartnerConfigKey.KEY_DESCRIPTION_LINK_TEXT_COLOR,
   PartnerConfigKey.KEY_DESCRIPTION_FONT_FAMILY,
+  PartnerConfigKey.KEY_DESCRIPTION_TEXT_MARGIN_TOP,
+  PartnerConfigKey.KEY_DESCRIPTION_TEXT_MARGIN_BOTTOM,
   PartnerConfigKey.KEY_CONTENT_TEXT_SIZE,
   PartnerConfigKey.KEY_CONTENT_TEXT_COLOR,
   PartnerConfigKey.KEY_CONTENT_LINK_TEXT_COLOR,
   PartnerConfigKey.KEY_CONTENT_FONT_FAMILY,
   PartnerConfigKey.KEY_CONTENT_LAYOUT_GRAVITY,
+  PartnerConfigKey.KEY_CONTENT_PADDING_TOP,
+  PartnerConfigKey.KEY_ITEMS_TITLE_TEXT_SIZE,
+  PartnerConfigKey.KEY_ITEMS_SUMMARY_TEXT_SIZE,
+  PartnerConfigKey.KEY_ITEMS_SUMMARY_MARGIN_TOP,
+  PartnerConfigKey.KEY_ITEMS_TITLE_FONT_FAMILY,
+  PartnerConfigKey.KEY_ITEMS_SUMMARY_FONT_FAMILY,
+  PartnerConfigKey.KEY_ITEMS_PADDING_TOP,
+  PartnerConfigKey.KEY_ITEMS_PADDING_BOTTOM,
+  PartnerConfigKey.KEY_ITEMS_MIN_HEIGHT,
+  PartnerConfigKey.KEY_ITEMS_DIVIDER_SHOWN,
   PartnerConfigKey.KEY_PROGRESS_ILLUSTRATION_DEFAULT,
   PartnerConfigKey.KEY_PROGRESS_ILLUSTRATION_ACCOUNT,
   PartnerConfigKey.KEY_PROGRESS_ILLUSTRATION_CONNECTION,
   PartnerConfigKey.KEY_PROGRESS_ILLUSTRATION_UPDATE,
   PartnerConfigKey.KEY_PROGRESS_ILLUSTRATION_DISPLAY_MINIMUM_MS,
+  PartnerConfigKey.KEY_LOADING_LOTTIE_ACCOUNT,
+  PartnerConfigKey.KEY_LOADING_LOTTIE_CONNECTION,
+  PartnerConfigKey.KEY_LOADING_LOTTIE_DEFAULT,
+  PartnerConfigKey.KEY_LOADING_LOTTIE_UPDATE,
+  PartnerConfigKey.KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_DEFAULT,
+  PartnerConfigKey.KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_ACCOUNT,
+  PartnerConfigKey.KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_CONNECTION,
+  PartnerConfigKey.KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_UPDATE,
+  PartnerConfigKey.KEY_LOADING_DARK_THEME_CUSTOMIZATION_DEFAULT,
+  PartnerConfigKey.KEY_LOADING_DARK_THEME_CUSTOMIZATION_ACCOUNT,
+  PartnerConfigKey.KEY_LOADING_DARK_THEME_CUSTOMIZATION_CONNECTION,
+  PartnerConfigKey.KEY_LOADING_DARK_THEME_CUSTOMIZATION_UPDATE,
+  PartnerConfigKey.KEY_TRANSITION_TYPE,
 })
 // TODO: can be removed and always reference PartnerConfig.getResourceName()?
 @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
@@ -87,9 +128,15 @@
   // such that it is compatible with a light navigation bar background.
   String KEY_LIGHT_NAVIGATION_BAR = "setup_compat_light_navigation_bar";
 
+  // Navigation bar divider color
+  String KEY_NAVIGATION_BAR_DIVIDER_COLOR = "setup_compat_navigation_bar_divider_color";
+
   // Background color of the footer bar.
   String KEY_FOOTER_BAR_BG_COLOR = "setup_compat_footer_bar_bg_color";
 
+  // The min height of the footer bar
+  String KEY_FOOTER_BAR_MIN_HEIGHT = "setup_compat_footer_bar_min_height";
+
   // The font face used in footer buttons. This must be a string reference to a font that is
   // available in the system. Font references (@font or @xml) are not allowed.
   String KEY_FOOTER_BUTTON_FONT_FAMILY = "setup_compat_footer_button_font_family";
@@ -127,12 +174,18 @@
   // Corner radius of the footer buttons
   String KEY_FOOTER_BUTTON_RADIUS = "setup_compat_footer_button_radius";
 
-  // Ripple color alpha of the footer button
+  // Ripple color alpha of the footer buttons
   String KEY_FOOTER_BUTTON_RIPPLE_ALPHA = "setup_compat_footer_button_ripple_alpha";
 
-  // Text size of the footer button
+  // Text size of the footer buttons
   String KEY_FOOTER_BUTTON_TEXT_SIZE = "setup_compat_footer_button_text_size";
 
+  // The font face used in footer buttons {0 = NORMAL}, {1 = BOLD}, {2 = ITALIC}, {3 = BOLD_ITALIC}
+  String KEY_FOOTER_BUTTON_TEXT_STYLE = "setup_compat_footer_button_text_style";
+
+  // The min height of the footer buttons
+  String KEY_FOOTER_BUTTON_MIN_HEIGHT = "setup_compat_footer_button_min_height";
+
   // Disabled background alpha of the footer buttons
   String KEY_FOOTER_BUTTON_DISABLED_ALPHA = "setup_compat_footer_button_disabled_alpha";
 
@@ -154,6 +207,12 @@
   // Background color of layout
   String KEY_LAYOUT_BACKGROUND_COLOR = "setup_design_layout_bg_color";
 
+  // Margin start of the layout
+  String KEY_LAYOUT_MARGIN_START = "setup_design_layout_margin_start";
+
+  // Margin end of the layout
+  String KEY_LAYOUT_MARGIN_END = "setup_design_layout_margin_end";
+
   // Text size of the header
   String KEY_HEADER_TEXT_SIZE = "setup_design_header_text_size";
 
@@ -163,12 +222,44 @@
   // Font family of the header
   String KEY_HEADER_FONT_FAMILY = "setup_design_header_font_family";
 
+  // Margin top of the header text
+  String KEY_HEADER_TEXT_MARGIN_TOP = "setup_design_header_text_margin_top";
+
+  // Margin bottom of the header text
+  String KEY_HEADER_TEXT_MARGIN_BOTTOM = "setup_design_header_text_margin_bottom";
+
   // Gravity of the header, icon and description
   String KEY_LAYOUT_GRAVITY = "setup_design_layout_gravity";
 
+  // Margin top of the icon
+  String KEY_ICON_MARGIN_TOP = "setup_design_icon_margin_top";
+
+  // Size of the icon
+  String KEY_ICON_SIZE = "setup_design_icon_size";
+
   // Background color of the header area
   String KEY_HEADER_AREA_BACKGROUND_COLOR = "setup_design_header_area_background_color";
 
+  // Margin bottom of the header container
+  String KEY_HEADER_CONTAINER_MARGIN_BOTTOM = "setup_design_header_container_margin_bottom";
+
+  // Auto text size enabled status
+  String KEY_HEADER_AUTO_SIZE_ENABLED = "setup_design_header_auto_size_enabled";
+
+  // Max text size of header when auto size enabled. Ignored if auto size is false.
+  String KEY_HEADER_AUTO_SIZE_MAX_TEXT_SIZE = "setup_design_header_auto_size_max_text_size";
+
+  // Min text size of header when auto size enabled. Ignored if auto size is false.
+  String KEY_HEADER_AUTO_SIZE_MIN_TEXT_SIZE = "setup_design_header_auto_size_min_text_size";
+
+  // The max lines of the max text size when auto size enabled. Ignored if auto size is false.
+  String KEY_HEADER_AUTO_SIZE_MAX_LINE_OF_MAX_SIZE =
+      "setup_design_header_auto_size_max_line_of_max_size";
+
+  // Extra line spacing of header when auto size enabled. Ignored if auto size is false.
+  String KEY_HEADER_AUTO_SIZE_LINE_SPACING_EXTRA =
+      "setup_design_header_auto_size_line_spacing_extra";
+
   // Text size of the description
   String KEY_DESCRIPTION_TEXT_SIZE = "setup_design_description_text_size";
 
@@ -181,6 +272,12 @@
   // Font family of the description
   String KEY_DESCRIPTION_FONT_FAMILY = "setup_design_description_font_family";
 
+  // Margin top of the header text
+  String KEY_DESCRIPTION_TEXT_MARGIN_TOP = "setup_design_description_text_margin_top";
+
+  // Margin bottom of the header text
+  String KEY_DESCRIPTION_TEXT_MARGIN_BOTTOM = "setup_design_description_text_margin_bottom";
+
   // Text size of the body content text
   String KEY_CONTENT_TEXT_SIZE = "setup_design_content_text_size";
 
@@ -196,6 +293,36 @@
   // Gravity of the body content text
   String KEY_CONTENT_LAYOUT_GRAVITY = "setup_design_content_layout_gravity";
 
+  // The padding top of the content
+  String KEY_CONTENT_PADDING_TOP = "setup_design_content_padding_top";
+
+  // The title text size of list items.
+  String KEY_ITEMS_TITLE_TEXT_SIZE = "setup_design_items_title_text_size";
+
+  // The summary text size of list items.
+  String KEY_ITEMS_SUMMARY_TEXT_SIZE = "setup_design_items_summary_text_size";
+
+  // The summary margin top of list items.
+  String KEY_ITEMS_SUMMARY_MARGIN_TOP = "setup_design_items_summary_margin_top";
+
+  // The title font family of list items.
+  String KEY_ITEMS_TITLE_FONT_FAMILY = "setup_design_items_title_font_family";
+
+  // The summary font family of list items.
+  String KEY_ITEMS_SUMMARY_FONT_FAMILY = "setup_design_items_summary_font_family";
+
+  // The padding top of list items.
+  String KEY_ITEMS_PADDING_TOP = "setup_design_items_padding_top";
+
+  // The padding bottom of list items.
+  String KEY_ITEMS_PADDING_BOTTOM = "setup_design_items_padding_bottom";
+
+  // The minimum height of list items.
+  String KEY_ITEMS_MIN_HEIGHT = "setup_design_items_min_height";
+
+  // The divider of list items are showing.
+  String KEY_ITEMS_DIVIDER_SHOWN = "setup_design_items_divider_shown";
+
   // The animation of loading screen used in those activities which is non of below type.
   String KEY_PROGRESS_ILLUSTRATION_DEFAULT = "progress_illustration_custom_default";
 
@@ -214,4 +341,59 @@
 
   // The minimum illustration display time, set to 0 may cause the illustration stuck
   String KEY_PROGRESS_ILLUSTRATION_DISPLAY_MINIMUM_MS = "progress_illustration_display_minimum_ms";
+
+  // The animation for S+ devices used in those screens waiting for non of below type.
+  String KEY_LOADING_LOTTIE_DEFAULT = "loading_animation_custom_default";
+
+  // The animation for S+ devices used in those screens which is processing account info or related
+  // functions.
+  // For example:com.google.android.setupwizard.LOAD_ADD_ACCOUNT_INTENT
+  String KEY_LOADING_LOTTIE_ACCOUNT = "loading_animation_custom_account";
+
+  // The animation for S+ devices used in those screens which is processing data connection.
+  // For example:com.android.setupwizard.CAPTIVE_PORTAL
+  String KEY_LOADING_LOTTIE_CONNECTION = "loading_animation_custom_connection";
+
+  // The animation for S+ devices used in those screens which is updating devices.
+  // For example:com.google.android.setupwizard.COMPAT_EARLY_UPDATE
+  String KEY_LOADING_LOTTIE_UPDATE = "loading_animation_custom_update";
+
+  // A string-array to list all the key path and color map for default animation for light theme.
+  // For example: background:#FFFFFF
+  String KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_DEFAULT =
+      "loading_light_theme_customization_default";
+
+  // A string-array to list all the key path and color map for account animation for light theme.
+  // For example: background:#FFFFFF
+  String KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_ACCOUNT =
+      "loading_light_theme_customization_account";
+
+  // A string-array to list all the key path and color map for connection animation for light theme.
+  // For example: background:#FFFFFF
+  String KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_CONNECTION =
+      "loading_light_theme_customization_connection";
+
+  // A string-array to list all the key path and color map for update animation for light theme.
+  // For example: background:#FFFFFF
+  String KEY_LOADING_LIGHT_THEME_CUSTOMIZATION_UPDATE = "loading_light_theme_customization_update";
+
+  // A string-array to list all the key path and color map for default animation for dark theme.
+  // For example: background:#000000
+  String KEY_LOADING_DARK_THEME_CUSTOMIZATION_DEFAULT = "loading_dark_theme_customization_default";
+
+  // A string-array to list all the key path and color map for account animation for dark theme.
+  // For example: background:#000000
+  String KEY_LOADING_DARK_THEME_CUSTOMIZATION_ACCOUNT = "loading_dark_theme_customization_account";
+
+  // A string-array to list all the key path and color map for connection animation for dark theme.
+  // For example: background:#000000
+  String KEY_LOADING_DARK_THEME_CUSTOMIZATION_CONNECTION =
+      "loading_dark_theme_customization_connection";
+
+  // A string-array to list all the key path and color map for update animation for dark theme.
+  // For example: background:#000000
+  String KEY_LOADING_DARK_THEME_CUSTOMIZATION_UPDATE = "loading_dark_theme_customization_update";
+
+  // The transition type between activities
+  String KEY_TRANSITION_TYPE = "setup_design_transition_type";
 }
diff --git a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/ResourceEntry.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/ResourceEntry.java
index 8f7c9d8..c8b8623 100644
--- a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/ResourceEntry.java
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/ResourceEntry.java
@@ -23,10 +23,10 @@
 import android.os.Build;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
+import android.util.Log;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
-import android.util.Log;
 
 /**
  * A potentially cross-package resource entry, which can then be retrieved using {@link
diff --git a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/Util.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/Util.java
new file mode 100644
index 0000000..8ac4c2d
--- /dev/null
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/Util.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 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 com.google.android.setupcompat.partnerconfig;
+
+import android.content.res.Configuration;
+
+/** The utility to help partner to config. */
+public final class Util {
+
+  public static boolean isNightMode(Configuration configuration) {
+    return (configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK)
+        == Configuration.UI_MODE_NIGHT_YES;
+  }
+
+  private Util() {}
+}