Merge QQ3A.200605.002 into master

Bug: 158095402
Merged-In: Ia6d4d0b579c662785ad435e69ab9f84da1de0a76
Change-Id: Ib1d6067fa41b5573d0e8b96bb22f00c4a4462a5f
diff --git a/library/main/res/anim/progress_indeterminate_horizontal_rect1.xml b/library/main/res/anim/progress_indeterminate_horizontal_rect1.xml
new file mode 100644
index 0000000..b541364
--- /dev/null
+++ b/library/main/res/anim/progress_indeterminate_horizontal_rect1.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2020 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+  <objectAnimator
+      android:duration="2000"
+      android:propertyXName="translateX"
+      android:pathData="M -522.59998,0 c 48.89972,0 166.02656,0 301.21729,0 c 197.58128,0 420.9827,0 420.9827,0 "
+      android:interpolator="@interpolator/progress_indeterminate_horizontal_rect1_translatex"
+      android:repeatCount="infinite" />
+  <objectAnimator
+      android:duration="2000"
+      android:propertyYName="scaleX"
+      android:pathData="M 0 0.1 L 1 0.826849212646 L 2 0.1"
+      android:interpolator="@interpolator/progress_indeterminate_horizontal_rect1_scalex"
+      android:repeatCount="infinite" />
+</set>
\ No newline at end of file
diff --git a/library/main/res/anim/progress_indeterminate_horizontal_rect2.xml b/library/main/res/anim/progress_indeterminate_horizontal_rect2.xml
new file mode 100644
index 0000000..defc80f
--- /dev/null
+++ b/library/main/res/anim/progress_indeterminate_horizontal_rect2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2020 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+  <objectAnimator
+      android:duration="2000"
+      android:propertyXName="translateX"
+      android:pathData="M -197.60001,0 c 14.28182,0 85.07782,0 135.54689,0 c 54.26191,0 90.42461,0 168.24331,0 c 144.72154,0 316.40982,0 316.40982,0 "
+      android:interpolator="@interpolator/progress_indeterminate_horizontal_rect2_translatex"
+      android:repeatCount="infinite" />
+  <objectAnimator
+      android:duration="2000"
+      android:propertyYName="scaleX"
+      android:pathData="M 0.0,0.1 L 1.0,0.571379510698 L 2.0,0.909950256348 L 3.0,0.1"
+      android:interpolator="@interpolator/progress_indeterminate_horizontal_rect2_scalex"
+      android:repeatCount="infinite" />
+</set>
\ No newline at end of file
diff --git a/library/main/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml b/library/main/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml
new file mode 100644
index 0000000..e58fb30
--- /dev/null
+++ b/library/main/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2020 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.
+-->
+<!-- Variant of progress_indeterminate_horizontal_material in frameworks/base/core/res, which
+     draws the whole height of the progress bar instead having blank space above and below the
+     bar. -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/vector_drawable_progress_indeterminate_horizontal_trimmed">
+  <target
+      android:name="rect2_grp"
+      android:animation="@anim/progress_indeterminate_horizontal_rect2"/>
+  <target
+      android:name="rect1_grp"
+      android:animation="@anim/progress_indeterminate_horizontal_rect1"/>
+</animated-vector>
\ No newline at end of file
diff --git a/library/main/res/drawable/vector_drawable_progress_indeterminate_horizontal_trimmed.xml b/library/main/res/drawable/vector_drawable_progress_indeterminate_horizontal_trimmed.xml
new file mode 100644
index 0000000..c34f96b
--- /dev/null
+++ b/library/main/res/drawable/vector_drawable_progress_indeterminate_horizontal_trimmed.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2020 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.
+-->
+<!-- Variant of vector_drawable_progress_indeterminate_horizontal in frameworks/base/core/res, which
+     draws the whole height of the progress bar instead having blank space above and below the
+     bar. -->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="360dp"
+    android:height="10dp"
+    android:viewportHeight="10"
+    android:viewportWidth="360">
+  <group
+      android:name="progress_group"
+      android:translateX="180"
+      android:translateY="5">
+    <path
+        android:name="background_track"
+        android:fillAlpha="?android:attr/disabledAlpha"
+        android:fillColor="?android:attr/colorControlActivated"
+        android:pathData="M -180.0,-5.0 l 360.0,0 l 0,10.0 l -360.0,0 Z"/>
+    <group
+        android:name="rect2_grp"
+        android:scaleX="0.1"
+        android:translateX="-197.60001">
+      <path
+          android:name="rect2"
+          android:fillColor="?android:attr/colorControlActivated"
+          android:pathData="M -144.0,-5.0 l 288.0,0 l 0,10.0 l -288.0,0 Z"/>
+    </group>
+    <group
+        android:name="rect1_grp"
+        android:scaleX="0.1"
+        android:translateX="-522.59998">
+      <path
+          android:name="rect1"
+          android:fillColor="?android:attr/colorControlActivated"
+          android:pathData="M -144.0,-5.0 l 288.0,0 l 0,10.0 l -288.0,0 Z"/>
+    </group>
+  </group>
+</vector>
\ No newline at end of file
diff --git a/library/main/res/values/dimens.xml b/library/main/res/interpolator/progress_indeterminate_horizontal_rect1_scalex.xml
similarity index 60%
rename from library/main/res/values/dimens.xml
rename to library/main/res/interpolator/progress_indeterminate_horizontal_rect1_scalex.xml
index 4a66971..acf67a6 100644
--- a/library/main/res/values/dimens.xml
+++ b/library/main/res/interpolator/progress_indeterminate_horizontal_rect1_scalex.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-    Copyright (C) 2018 The Android Open Source Project
+    Copyright (C) 2020 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,
@@ -14,7 +14,5 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<resources>
-    <!-- Elevation used to create a drop shadow on the title bar. -->
-    <dimen name="title_bar_drop_shadow_elevation">16dp</dimen>
-</resources>
\ No newline at end of file
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0 0 L 0.3665 0 C 0.47252618112021,0.062409910275 0.61541608570164,0.5 0.68325,0.5 C 0.75475061236836,0.5 0.75725829093844,0.814510098964 1.0,1.0" />
\ No newline at end of file
diff --git a/library/main/res/interpolator/progress_indeterminate_horizontal_rect1_translatex.xml b/library/main/res/interpolator/progress_indeterminate_horizontal_rect1_translatex.xml
new file mode 100644
index 0000000..3b6b023
--- /dev/null
+++ b/library/main/res/interpolator/progress_indeterminate_horizontal_rect1_translatex.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2020 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.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 L 0.2 0 C 0.3958333333336,0.0 0.474845090492,0.206797621729 0.5916666666664,0.417082932942 C 0.7151610251224,0.639379624869 0.81625,0.974556908664 1.0,1.0 " />
+
diff --git a/library/main/res/interpolator/progress_indeterminate_horizontal_rect2_scalex.xml b/library/main/res/interpolator/progress_indeterminate_horizontal_rect2_scalex.xml
new file mode 100644
index 0000000..0ca9752
--- /dev/null
+++ b/library/main/res/interpolator/progress_indeterminate_horizontal_rect2_scalex.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2020 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.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 C 0.06834272400867,0.01992566661414 0.19220331656133,0.15855429260523 0.33333333333333,0.34926160892842 C 0.38410433133433,0.41477913453861 0.54945792615267,0.68136029463551 0.66666666666667,0.68279962777002 C 0.752586273196,0.68179620963216 0.737253971954,0.878896194318 1,1" />
\ No newline at end of file
diff --git a/library/main/res/interpolator/progress_indeterminate_horizontal_rect2_translatex.xml b/library/main/res/interpolator/progress_indeterminate_horizontal_rect2_translatex.xml
new file mode 100644
index 0000000..f663796
--- /dev/null
+++ b/library/main/res/interpolator/progress_indeterminate_horizontal_rect2_translatex.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2020 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.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 C 0.0375,0.0 0.128764607715,0.0895380946618 0.25,0.218553507947 C 0.322410320025,0.295610602487 0.436666666667,0.417591408114 0.483333333333,0.489826169306 C 0.69,0.80972296795 0.793333333333,0.950016125212 1.0,1.0 " />
\ No newline at end of file
diff --git a/library/main/res/layout/car_setup_wizard_toolbar.xml b/library/main/res/layout/car_setup_wizard_toolbar.xml
index d28a616..5c5703b 100644
--- a/library/main/res/layout/car_setup_wizard_toolbar.xml
+++ b/library/main/res/layout/car_setup_wizard_toolbar.xml
@@ -18,10 +18,8 @@
      standard Car Toolbar/Application Bar, it doesn't require the same functionality, so it
      doesn't extend it.
 -->
-<!-- Note: This layout needs a background in order for elevation to show up. -->
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:background="?attr/android:windowBackground"
     android:layout_width="match_parent"
     android:layout_height="@dimen/car_app_bar_height">
 
@@ -75,12 +73,23 @@
             android:layout="@layout/primary_button"/>
     </LinearLayout>
 
+    <ImageView
+        android:id="@+id/divider"
+        android:layout_width="match_parent"
+        android:layout_height="2dp"
+        android:background="@color/car_suw_tint"
+        android:layout_above="@id/progress_bar"
+        android:layout_alignWithParentIfMissing="true"/>
+
     <ProgressBar
         android:id="@+id/progress_bar"
         style="?android:attr/progressBarStyleHorizontal"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_height="2dp"
+        android:minHeight="0dp"
+        android:maxHeight="20dp"
         android:layout_alignParentBottom="true"
+        android:indeterminateDrawable="@drawable/progress_indeterminate_horizontal_material_trimmed"
         android:indeterminateTint="?android:attr/colorAccent"
         android:indeterminateTintMode="src_in"/>
 </RelativeLayout>
diff --git a/library/main/src/com/android/car/setupwizardlib/BaseActivity.java b/library/main/src/com/android/car/setupwizardlib/BaseActivity.java
index 42137df..4fe59e7 100644
--- a/library/main/src/com/android/car/setupwizardlib/BaseActivity.java
+++ b/library/main/src/com/android/car/setupwizardlib/BaseActivity.java
@@ -458,20 +458,6 @@
     }
 
     /**
-     * Adds elevation to the title bar in order to produce a drop shadow.
-     */
-    protected void addElevationToTitleBar(boolean animate) {
-        mCarSetupWizardLayout.addElevationToTitleBar(animate);
-    }
-
-    /**
-     * Removes the elevation from the title bar using an animation.
-     */
-    protected void removeElevationFromTitleBar(boolean animate) {
-        mCarSetupWizardLayout.removeElevationFromTitleBar(animate);
-    }
-
-    /**
      * Sets whether the progress bar is visible.
      */
     protected void setProgressBarVisible(boolean visible) {
diff --git a/library/main/src/com/android/car/setupwizardlib/BaseSetupWizardActivity.java b/library/main/src/com/android/car/setupwizardlib/BaseSetupWizardActivity.java
index 910f37e..cbf47f1 100644
--- a/library/main/src/com/android/car/setupwizardlib/BaseSetupWizardActivity.java
+++ b/library/main/src/com/android/car/setupwizardlib/BaseSetupWizardActivity.java
@@ -111,7 +111,7 @@
     protected void onStart() {
         super.onStart();
         // Must be done here so that the SystemUI is hidden when back button is clicked
-        CarSetupWizardUiUtils.maybeHideSystemUI(this);
+        CarSetupWizardUiUtils.hideSystemUI(this);
         // Fragment commits are not allowed once the Activity's state has been saved. Once
         // onStart() has been called, the FragmentManager should now allow commits.
         mAllowFragmentCommits = true;
@@ -156,7 +156,7 @@
     public void onWindowFocusChanged(boolean hasFocus) {
         super.onWindowFocusChanged(hasFocus);
         if (hasFocus) {
-            CarSetupWizardUiUtils.maybeHideSystemUI(this);
+            CarSetupWizardUiUtils.hideSystemUI(this);
         }
     }
 
@@ -266,21 +266,14 @@
      * Moves to the next Activity in the SetupWizard flow, and save the intent data.
      */
     protected void nextAction(int resultCode, Intent data) {
-        if (resultCode == RESULT_CANCELED) {
-            throw new IllegalArgumentException("Cannot call nextAction with RESULT_CANCELED");
-        }
-        setResultCode(resultCode, data);
-        if (mNextActionAlreadyTriggered) {
-            Log.v("CarSetupWizard",
-                    "BaseSetupWizardActivity: nextAction triggered multiple times without"
-                            + "page refresh, ignoring.");
-            return;
-        }
-        mNextActionAlreadyTriggered = true;
-        onNextActionInvoked();
-        Intent nextIntent =
-                CarWizardManagerHelper.getNextIntent(getIntent(), mResultCode, mResultData);
-        startActivity(nextIntent);
+        launchNextAction(resultCode, data, /* forResult= */ false);
+    }
+
+    /**
+     * Moves to the next Activity in the SetupWizard flow. Start next activity for result.
+     */
+    protected void nextActionForResult(int resultCode) {
+        launchNextAction(resultCode, null, /* forResult= */ true);
     }
 
     /**
@@ -463,26 +456,34 @@
     }
 
     /**
-     * Adds elevation to the title bar in order to produce a drop shadow.
-     */
-    protected void addElevationToTitleBar(boolean animate) {
-        mCarSetupWizardLayout.addElevationToTitleBar(animate);
-    }
-
-    /**
-     * Removes the elevation from the title bar using an animation.
-     */
-    protected void removeElevationFromTitleBar(boolean animate) {
-        mCarSetupWizardLayout.removeElevationFromTitleBar(animate);
-    }
-
-    /**
      * Sets whether the progress bar is visible.
      */
     protected void setProgressBarVisible(boolean visible) {
         mCarSetupWizardLayout.setProgressBarVisible(visible);
     }
 
+    private void launchNextAction(int resultCode, Intent data, boolean forResult) {
+        if (resultCode == RESULT_CANCELED) {
+            throw new IllegalArgumentException("Cannot call nextAction with RESULT_CANCELED");
+        }
+        setResultCode(resultCode, data);
+        if (mNextActionAlreadyTriggered) {
+            Log.v("CarSetupWizard",
+                    "BaseSetupWizardActivity: nextAction triggered multiple times without"
+                            + "page refresh, ignoring.");
+            return;
+        }
+        mNextActionAlreadyTriggered = true;
+        onNextActionInvoked();
+        Intent nextIntent =
+                CarWizardManagerHelper.getNextIntent(getIntent(), mResultCode, mResultData);
+        if (forResult) {
+            startActivityForResult(nextIntent, REQUEST_CODE_NEXT);
+        } else  {
+            startActivity(nextIntent);
+        }
+    }
+
     @VisibleForTesting
     boolean getAllowFragmentCommits() {
         return mAllowFragmentCommits;
diff --git a/library/main/src/com/android/car/setupwizardlib/CarSetupWizardBaseLayout.java b/library/main/src/com/android/car/setupwizardlib/CarSetupWizardBaseLayout.java
index 1ef99bb..526a5ca 100644
--- a/library/main/src/com/android/car/setupwizardlib/CarSetupWizardBaseLayout.java
+++ b/library/main/src/com/android/car/setupwizardlib/CarSetupWizardBaseLayout.java
@@ -16,9 +16,9 @@
 
 package com.android.car.setupwizardlib;
 
-import android.animation.ValueAnimator;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
@@ -59,11 +59,10 @@
  */
 class CarSetupWizardBaseLayout extends LinearLayout {
     private static final String TAG = CarSetupWizardBaseLayout.class.getSimpleName();
-    private static final int ANIMATION_DURATION_MS = 100;
+    private static final int INVALID_COLOR = 0;
 
     private View mBackButton;
     private View mTitleBar;
-    private Float mTitleBarElevation;
     private TextView mToolbarTitle;
     private PartnerConfigHelper mPartnerConfigHelper;
 
@@ -82,6 +81,7 @@
     private boolean mPrimaryToolbarButtonFlat;
     private View.OnClickListener mPrimaryToolbarButtonOnClick;
     private Button mSecondaryToolbarButton;
+    private ImageView mDivider;
     private ProgressBar mProgressBar;
 
     CarSetupWizardBaseLayout(Context context) {
@@ -177,8 +177,6 @@
 
         // Se the title bar.
         setTitleBar(findViewById(R.id.application_bar));
-        mTitleBarElevation =
-                getContext().getResources().getDimension(R.dimen.title_bar_drop_shadow_elevation);
         int toolbarBgColor =
                 mPartnerConfigHelper.getColor(getContext(), PartnerConfig.CONFIG_TOOLBAR_BG_COLOR);
         if (toolbarBgColor != 0) {
@@ -218,6 +216,23 @@
         mProgressBar = findViewById(R.id.progress_bar);
         setProgressBarVisible(showProgressBar);
         setProgressBarIndeterminate(indeterminateProgressBar);
+        int tintColor = mPartnerConfigHelper.getColor(
+                getContext(),
+                PartnerConfig.CONFIG_LOADING_INDICATOR_COLOR);
+        if (tintColor != INVALID_COLOR) {
+            mProgressBar.setIndeterminateTintList(ColorStateList.valueOf(tintColor));
+        }
+
+        float lineWeight = mPartnerConfigHelper.getDimension(
+                getContext(),
+                PartnerConfig.CONFIG_LOADING_INDICATOR_LINE_WEIGHT);
+        if (lineWeight > 0) {
+            ViewGroup.LayoutParams layoutParams = mProgressBar.getLayoutParams();
+            layoutParams.height = Math.round(lineWeight);
+            mProgressBar.setLayoutParams(layoutParams);
+        }
+
+        initDivider();
 
         // Set orientation programmatically since the inflated layout uses <merge>
         setOrientation(LinearLayout.VERTICAL);
@@ -518,48 +533,6 @@
     }
 
     /**
-     * Adds elevation to the title bar in order to produce a drop shadow. An animation can be used
-     * in cases where a direct elevation changes would be too jarring.
-     *
-     * @param animate True when a smooth animation is wanted for the adding of the elevation.
-     */
-    public void addElevationToTitleBar(boolean animate) {
-        if (animate) {
-            ValueAnimator elevationAnimator =
-                    ValueAnimator.ofFloat(mTitleBar.getElevation(), mTitleBarElevation);
-            elevationAnimator
-                    .setDuration(ANIMATION_DURATION_MS)
-                    .addUpdateListener(
-                            animation -> mTitleBar.setElevation(
-                                    (float) animation.getAnimatedValue()));
-            elevationAnimator.start();
-        } else {
-            mTitleBar.setElevation(mTitleBarElevation);
-        }
-    }
-
-    /**
-     * Removes the elevation from the title bar, an animation can be used in cases where a direct
-     * elevation changes would be too jarring.
-     *
-     * @param animate True when a smooth animation is wanted for the removal of the elevation.
-     */
-    public void removeElevationFromTitleBar(boolean animate) {
-        if (animate) {
-            ValueAnimator elevationAnimator =
-                    ValueAnimator.ofFloat(mTitleBar.getElevation(), 0f);
-            elevationAnimator
-                    .setDuration(ANIMATION_DURATION_MS)
-                    .addUpdateListener(
-                            animation -> mTitleBar.setElevation(
-                                    (float) animation.getAnimatedValue()));
-            elevationAnimator.start();
-        } else {
-            mTitleBar.setElevation(0f);
-        }
-    }
-
-    /**
      * Sets the title bar view.
      */
     private void setTitleBar(View titleBar) {
@@ -714,6 +687,26 @@
         setButtonTextColor(primaryButton, textColorConfig);
     }
 
+    private void initDivider() {
+        mDivider = findViewById(R.id.divider);
+        float dividerHeight = mPartnerConfigHelper.getDimension(
+                getContext(),
+                PartnerConfig.CONFIG_TOOLBAR_DIVIDER_LINE_WEIGHT);
+        if (dividerHeight >= 0) {
+            ViewGroup.LayoutParams layoutParams = mDivider.getLayoutParams();
+            layoutParams.height = Math.round(dividerHeight);
+            mDivider.setLayoutParams(layoutParams);
+        }
+        if (dividerHeight > 0) {
+            Drawable dividerBg = mPartnerConfigHelper.getDrawable(
+                    getContext(),
+                    PartnerConfig.CONFIG_TOOLBAR_DIVIDER_BG);
+            if (dividerBg != null) {
+                mDivider.setBackground(dividerBg);
+            }
+        }
+    }
+
     private GradientDrawable getGradientDrawable(Button button) {
         Drawable drawable = button.getBackground();
         if (drawable instanceof InsetDrawable) {
@@ -732,6 +725,9 @@
     }
 
     private GradientDrawable getGradientDrawableFromInsetDrawable(InsetDrawable insetDrawable) {
-        return (GradientDrawable) insetDrawable.getDrawable();
+        if (insetDrawable.getDrawable() instanceof GradientDrawable) {
+            return (GradientDrawable) insetDrawable.getDrawable();
+        }
+        return null;
     }
 }
diff --git a/library/main/src/com/android/car/setupwizardlib/CarSetupWizardDesignLayout.java b/library/main/src/com/android/car/setupwizardlib/CarSetupWizardDesignLayout.java
index 45cf62f..62e52d9 100644
--- a/library/main/src/com/android/car/setupwizardlib/CarSetupWizardDesignLayout.java
+++ b/library/main/src/com/android/car/setupwizardlib/CarSetupWizardDesignLayout.java
@@ -18,7 +18,6 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.util.AttributeSet;
 
 import com.android.car.setupwizardlib.partner.PartnerConfig;
@@ -56,12 +55,5 @@
         if (bgColor != 0) {
             setBackgroundColor(bgColor);
         }
-
-        int tintColor = partnerConfigHelper.getColor(
-                context,
-                PartnerConfig.CONFIG_LOADING_INDICATOR_COLOR);
-        if (tintColor != 0) {
-            getProgressBar().setIndeterminateTintList(ColorStateList.valueOf(tintColor));
-        }
     }
 }
diff --git a/library/main/src/com/android/car/setupwizardlib/CarSetupWizardLayout.java b/library/main/src/com/android/car/setupwizardlib/CarSetupWizardLayout.java
index 554762f..9d30220 100644
--- a/library/main/src/com/android/car/setupwizardlib/CarSetupWizardLayout.java
+++ b/library/main/src/com/android/car/setupwizardlib/CarSetupWizardLayout.java
@@ -15,7 +15,6 @@
  */
 package com.android.car.setupwizardlib;
 
-import android.animation.ValueAnimator;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.TypedArray;
@@ -61,11 +60,9 @@
 @Deprecated
 public class CarSetupWizardLayout extends LinearLayout {
     private static final String TAG = CarSetupWizardLayout.class.getSimpleName();
-    private static final int ANIMATION_DURATION_MS = 100;
 
     private View mBackButton;
     private View mTitleBar;
-    private Float mTitleBarElevation;
     private TextView mToolbarTitle;
     private PartnerConfigHelper mPartnerConfigHelper;
 
@@ -178,8 +175,6 @@
 
         // Se the title bar.
         setTitleBar(findViewById(R.id.application_bar));
-        mTitleBarElevation =
-                getContext().getResources().getDimension(R.dimen.title_bar_drop_shadow_elevation);
         int toolbarBgColor =
                 mPartnerConfigHelper.getColor(getContext(), PartnerConfig.CONFIG_TOOLBAR_BG_COLOR);
         if (toolbarBgColor != 0) {
@@ -535,48 +530,6 @@
     }
 
     /**
-     * Adds elevation to the title bar in order to produce a drop shadow. An animation can be used
-     * in cases where a direct elevation changes would be too jarring.
-     *
-     * @param animate True when a smooth animation is wanted for the adding of the elevation.
-     */
-    public void addElevationToTitleBar(boolean animate) {
-        if (animate) {
-            ValueAnimator elevationAnimator =
-                    ValueAnimator.ofFloat(mTitleBar.getElevation(), mTitleBarElevation);
-            elevationAnimator
-                    .setDuration(ANIMATION_DURATION_MS)
-                    .addUpdateListener(
-                            animation -> mTitleBar.setElevation(
-                                    (float) animation.getAnimatedValue()));
-            elevationAnimator.start();
-        } else {
-            mTitleBar.setElevation(mTitleBarElevation);
-        }
-    }
-
-    /**
-     * Removes the elevation from the title bar, an animation can be used in cases where a direct
-     * elevation changes would be too jarring.
-     *
-     * @param animate True when a smooth animation is wanted for the removal of the elevation.
-     */
-    public void removeElevationFromTitleBar(boolean animate) {
-        if (animate) {
-            ValueAnimator elevationAnimator =
-                    ValueAnimator.ofFloat(mTitleBar.getElevation(), 0f);
-            elevationAnimator
-                    .setDuration(ANIMATION_DURATION_MS)
-                    .addUpdateListener(
-                            animation -> mTitleBar.setElevation(
-                                    (float) animation.getAnimatedValue()));
-            elevationAnimator.start();
-        } else {
-            mTitleBar.setElevation(0f);
-        }
-    }
-
-    /**
      * Sets the title bar view.
      */
     private void setTitleBar(View titleBar) {
diff --git a/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfig.java b/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfig.java
index d3f6ea2..8946b7a 100644
--- a/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfig.java
+++ b/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfig.java
@@ -19,9 +19,6 @@
 /** Resources that can be customized by partner overlay APK. */
 public enum PartnerConfig {
 
-    CONFIG_IS_IMMERSIVE(
-            PartnerConfigKey.KEY_IS_IMMERSIVE, ResourceType.BOOLEAN),
-
     CONFIG_TOOLBAR_BG_COLOR(
             PartnerConfigKey.KEY_TOOLBAR_BG_COLOR, ResourceType.COLOR),
 
@@ -64,9 +61,18 @@
     CONFIG_TOOLBAR_SECONDARY_BUTTON_TEXT_COLOR(
             PartnerConfigKey.KEY_TOOLBAR_SECONDARY_BUTTON_TEXT_COLOR, ResourceType.COLOR),
 
+    CONFIG_TOOLBAR_DIVIDER_BG(
+            PartnerConfigKey.KEY_TOOLBAR_DIVIDER_BG, ResourceType.DRAWABLE),
+
+    CONFIG_TOOLBAR_DIVIDER_LINE_WEIGHT(
+            PartnerConfigKey.KEY_TOOLBAR_DIVIDER_LINE_WEIGHT, ResourceType.DIMENSION),
+
     CONFIG_LOADING_INDICATOR_COLOR(
             PartnerConfigKey.KEY_LOADING_INDICATOR_COLOR, ResourceType.COLOR),
 
+    CONFIG_LOADING_INDICATOR_LINE_WEIGHT(
+            PartnerConfigKey.KEY_LOADING_INDICATOR_LINE_WEIGHT, ResourceType.DIMENSION),
+
     CONFIG_LAYOUT_BG_COLOR(
             PartnerConfigKey.KEY_LAYOUT_BG_COLOR, ResourceType.COLOR);
 
diff --git a/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfigKey.java b/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfigKey.java
index e98a533..de4aa9e 100644
--- a/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfigKey.java
+++ b/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfigKey.java
@@ -23,7 +23,6 @@
 
 @Retention(RetentionPolicy.SOURCE)
 @StringDef({
-        PartnerConfigKey.KEY_IS_IMMERSIVE,
         PartnerConfigKey.KEY_TOOLBAR_BG_COLOR,
         PartnerConfigKey.KEY_TOOLBAR_BUTTON_ICON_BACK,
         PartnerConfigKey.KEY_TOOLBAR_BUTTON_FONT_FAMILY,
@@ -38,15 +37,16 @@
         PartnerConfigKey.KEY_TOOLBAR_SECONDARY_BUTTON_BG,
         PartnerConfigKey.KEY_TOOLBAR_SECONDARY_BUTTON_BG_COLOR,
         PartnerConfigKey.KEY_TOOLBAR_SECONDARY_BUTTON_TEXT_COLOR,
+        PartnerConfigKey.KEY_TOOLBAR_DIVIDER_BG,
+        PartnerConfigKey.KEY_TOOLBAR_DIVIDER_LINE_WEIGHT,
         PartnerConfigKey.KEY_LOADING_INDICATOR_COLOR,
+        PartnerConfigKey.KEY_LOADING_INDICATOR_LINE_WEIGHT,
         PartnerConfigKey.KEY_LAYOUT_BG_COLOR
 })
 
 /** Resource names that can be customized by partner overlay APK. */
 public @interface PartnerConfigKey {
 
-    String KEY_IS_IMMERSIVE = "suw_compat_is_immersive";
-
     String KEY_TOOLBAR_BG_COLOR = "suw_compat_toolbar_bg_color";
 
     String KEY_TOOLBAR_BUTTON_ICON_BACK = "suw_compat_toolbar_button_icon_back";
@@ -77,7 +77,13 @@
     String KEY_TOOLBAR_SECONDARY_BUTTON_TEXT_COLOR =
             "suw_compat_toolbar_secondary_button_text_color";
 
-    String KEY_LOADING_INDICATOR_COLOR = "suw_design_loading_indicator_color";
+    String KEY_TOOLBAR_DIVIDER_BG = "suw_compat_toolbar_divider_bg";
+
+    String KEY_TOOLBAR_DIVIDER_LINE_WEIGHT = "suw_compat_toolbar_divider_line_weight";
+
+    String KEY_LOADING_INDICATOR_COLOR = "suw_compat_loading_indicator_color";
+
+    String KEY_LOADING_INDICATOR_LINE_WEIGHT = "suw_compat_loading_indicator_line_weight";
 
     String KEY_LAYOUT_BG_COLOR = "suw_design_layout_bg_color";
 }
diff --git a/library/main/src/com/android/car/setupwizardlib/summary/DeferredAction.java b/library/main/src/com/android/car/setupwizardlib/summary/DeferredAction.java
new file mode 100644
index 0000000..3add5be
--- /dev/null
+++ b/library/main/src/com/android/car/setupwizardlib/summary/DeferredAction.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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.android.car.setupwizardlib.summary;
+
+/**
+ * An instance of a summary action's deferred state. This includes the deferred notification
+ * description and the completion state.
+ */
+public class DeferredAction implements Comparable<DeferredAction> {
+
+    public final String deferredNotificationDescription;
+    public final boolean completed;
+    public final int priority;
+
+    public DeferredAction(String deferredNotificationDescription, boolean completed, int priority) {
+        this.deferredNotificationDescription = deferredNotificationDescription;
+        this.completed = completed;
+        this.priority = priority;
+    }
+
+    @Override
+    public int compareTo(DeferredAction o) {
+        if (o == null) {
+            return 1;
+        }
+        return priority - o.priority;
+    }
+}
diff --git a/library/main/src/com/android/car/setupwizardlib/summary/PartnerSummaryActionsCollector.java b/library/main/src/com/android/car/setupwizardlib/summary/PartnerSummaryActionsCollector.java
new file mode 100644
index 0000000..f0cc786
--- /dev/null
+++ b/library/main/src/com/android/car/setupwizardlib/summary/PartnerSummaryActionsCollector.java
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2019 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.android.car.setupwizardlib.summary;
+
+import android.annotation.Nullable;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Collects the actions provided by partners and compiles them into a list of {@link SummaryAction}
+ * items.
+ */
+public class PartnerSummaryActionsCollector {
+
+    private static final String TAG = "PartnerSummaryActionsCollector";
+
+    private static final String CONTENT_PROVIDER_INTENT_ACTION =
+            "com.google.android.car.setupwizard.SETUP_ACTIONS_STATE_PROVIDER";
+
+    // Methods for fetching info from the content provider.
+    private static final String METHOD_GET_ACTION_COMPLETION_STATE = "get_action_completion_state";
+    private static final String METHOD_GET_ACTION_SUMMARY_STATE = "get_action_summary_state";
+    private static final String METHOD_GET_DEFERRED_ACTION_STATE =
+            "get_deferred_action_state";
+    private static final String METHOD_GET_SUMMARY_ACTIONS = "get_summary_actions";
+
+    // Constants for fetching information from the bundles passed back by the content provider.
+    private static final String EXTRA_SUMMARY_ACTIONS_LIST = "summary_actions_list";
+    private static final String EXTRA_IS_ACTION_COMPLETED = "is_action_completed";
+
+    // Constants for information contained within the summary action bundle.
+    private static final String EXTRA_SUMMARY_ACTION_HAS_DEPENDENCY =
+            "summary_action_has_dependency";
+    private static final String EXTRA_SUMMARY_ACTION_DEPENDENCY_DESCRIPTION =
+            "summary_action_dependency_description";
+    private static final String EXTRA_SUMMARY_ACTION_TITLE = "summary_action_title";
+    private static final String EXTRA_SUMMARY_ACTION_DESCRIPTION = "summary_action_description";
+    private static final String EXTRA_SUMMARY_ACTION_REQUIRES_NETWORK =
+            "summary_action_requires_network";
+    private static final String EXTRA_SUMMARY_ACTION_WIZARD_SCRIPT = "summary_action_wizard_script";
+    private static final String EXTRA_SUMMARY_ACTION_PRIORITY = "summary_action_priority";
+    private static final String EXTRA_SUMMARY_ICON_RESOURCE_NAME =
+            "summary_action_icon_resource_name";
+    private static final String EXTRA_SUMMARY_COMPLETED_DESCRIPTION =
+            "summary_action_completed_description";
+    private static final String EXTRA_SUMMARY_ACTION_DEFERRED_NOTIFICATION_DESCRIPTION =
+            "summary_action_deferred_notification_description";
+
+    // Extra used as a key for the action id passed in to query summary action state.
+    private static final String EXTRA_ACTION_ID = "action_id";
+    private static PartnerSummaryActionsCollector sPartnerSummaryActionsCollector;
+    private final Context mContext;
+    private Uri mContentProviderUri;
+
+    /** private constructor, should use getter. */
+    private PartnerSummaryActionsCollector(Context context) {
+        mContext = context;
+        ResolveInfo resolveInfo = getSummaryContentProviderResolveInfo(context.getPackageManager());
+
+        if (resolveInfo == null) {
+            Log.e(TAG, "Could not find partner content provider, ignoring partner summary items.");
+            return;
+        }
+
+        mContentProviderUri = getSummaryContentProviderUri(resolveInfo);
+
+        if (mContentProviderUri == null) {
+            Log.e(TAG, "Could not fetch content provider URI, ignoring partner summary items.");
+        }
+    }
+
+    /** Gets the current instance of the {@link PartnerSummaryActionsCollector}. */
+    public static PartnerSummaryActionsCollector get(Context context) {
+        if (sPartnerSummaryActionsCollector == null) {
+            sPartnerSummaryActionsCollector = new PartnerSummaryActionsCollector(context);
+        }
+        return sPartnerSummaryActionsCollector;
+    }
+
+    /**
+     * Creates a summary action using the passed in completion state and summary state {@link
+     * Bundle}.
+     * This will pull out all relevant state such as title, description, dependencies, and anything
+     * else that defines a summary item. Returns null if the bundle does not have all the required
+     * state or is null.
+     */
+    @Nullable
+    private static SummaryAction buildSummaryAction(
+            boolean completed, Bundle summaryStateBundle) {
+        if (summaryStateBundle == null) {
+            return null;
+        }
+
+        String title = summaryStateBundle.getString(EXTRA_SUMMARY_ACTION_TITLE);
+        if (title == null) {
+            Log.e(TAG, "No title provided in summaryStateBundle: " + summaryStateBundle);
+            return null;
+        }
+
+        String scriptUri = summaryStateBundle.getString(EXTRA_SUMMARY_ACTION_WIZARD_SCRIPT);
+        if (scriptUri == null) {
+            Log.e(TAG, "No wizard script provided in summaryStateBundle: " + summaryStateBundle);
+            return null;
+        }
+
+        String description = summaryStateBundle.getString(EXTRA_SUMMARY_ACTION_DESCRIPTION, "");
+        boolean requiresNetwork =
+                summaryStateBundle.getBoolean(EXTRA_SUMMARY_ACTION_REQUIRES_NETWORK, false);
+        boolean hasUnfinishedDependency =
+                summaryStateBundle.getBoolean(EXTRA_SUMMARY_ACTION_HAS_DEPENDENCY, false);
+        String unfinishedDependencyDescription = null;
+        if (hasUnfinishedDependency) {
+            unfinishedDependencyDescription =
+                    summaryStateBundle.getString(EXTRA_SUMMARY_ACTION_DEPENDENCY_DESCRIPTION);
+        }
+        // Fetch priority, default 0 so that if no priority is provided they will be placed above
+        // the Google items which are located in 100-200.
+        int priority = summaryStateBundle.getInt(EXTRA_SUMMARY_ACTION_PRIORITY, 0);
+        String iconResourceName = null;
+        if (summaryStateBundle.containsKey(EXTRA_SUMMARY_ICON_RESOURCE_NAME)) {
+            iconResourceName = summaryStateBundle.getString(EXTRA_SUMMARY_ICON_RESOURCE_NAME, "");
+        }
+
+        String completedDescription =
+                summaryStateBundle.getString(EXTRA_SUMMARY_COMPLETED_DESCRIPTION, description);
+        return new SummaryAction(
+                title,
+                description,
+                requiresNetwork,
+                completed,
+                priority,
+                scriptUri,
+                hasUnfinishedDependency,
+                unfinishedDependencyDescription,
+                iconResourceName,
+                completedDescription);
+    }
+
+    /**
+     * Creates a {@link DeferredAction} based on the passed in completion state and deferred action
+     * state bundle. Will return null if there is no notification description or a null bundle.
+     */
+    private static DeferredAction buildDeferredAction(boolean completed,
+            Bundle deferredActionState) {
+        if (deferredActionState == null) {
+            Log.e(TAG, "Cannot build deferred action with null deferredActionState");
+            return null;
+        }
+
+        String deferredNotificationDescription = deferredActionState.getString(
+                EXTRA_SUMMARY_ACTION_DEFERRED_NOTIFICATION_DESCRIPTION);
+        if (deferredNotificationDescription == null) {
+            Log.v(TAG, "Cannot build deferred action with no notification description");
+            return null;
+        }
+
+        int priority = deferredActionState.getInt(EXTRA_SUMMARY_ACTION_PRIORITY, 0);
+        return new DeferredAction(deferredNotificationDescription, completed, priority);
+    }
+
+    private static ResolveInfo getSummaryContentProviderResolveInfo(PackageManager packageManager) {
+        Intent contentProviderQueryIntent = new Intent(CONTENT_PROVIDER_INTENT_ACTION);
+        List<ResolveInfo> queryResults =
+                packageManager.queryIntentContentProviders(contentProviderQueryIntent, 0);
+        Log.v(TAG, "Query results size before pruning for system packages: " + queryResults.size());
+        queryResults =
+                queryResults.stream()
+                        .filter(
+                                resolveInfo ->
+                                        resolveInfo.providerInfo != null
+                                                && resolveInfo.providerInfo.applicationInfo != null
+                                                && (resolveInfo.providerInfo.applicationInfo.flags
+                                                & ApplicationInfo.FLAG_SYSTEM)
+                                                != 0)
+                        .collect(Collectors.toList());
+        if (queryResults.size() > 1 || queryResults.isEmpty()) {
+            Log.v(
+                    TAG,
+                    "Found "
+                            + queryResults.size()
+                            + " content providers, there should be exactly 1 to show partner "
+                            + "actions. Ignoring"
+                            + " all partner actions.");
+            return null;
+        }
+        return queryResults.get(0);
+    }
+
+    private static Uri getSummaryContentProviderUri(ResolveInfo resolveInfo) {
+        if (resolveInfo.providerInfo == null || TextUtils.isEmpty(
+                resolveInfo.providerInfo.authority)) {
+            Log.e(TAG, "Incorrectly configured partner content provider");
+            return null;
+        }
+        return new Uri.Builder()
+                .scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(resolveInfo.providerInfo.authority)
+                .build();
+    }
+
+    /**
+     * Gets the list of provided partner summary actions. Will return an empty list if none are
+     * found or there is an error loading them.
+     */
+    public List<SummaryAction> getPartnerSummaryActions() {
+        if (mContentProviderUri == null) {
+            Log.e(TAG, "No content provider URI found, summary actions ignored");
+            return new ArrayList<>();
+        }
+        ArrayList<String> partnerSummaryActions;
+        try {
+            partnerSummaryActions = getPartnerSummaryActionsFromContentProvider(
+                    mContentProviderUri);
+        } catch (NullPointerException | IllegalArgumentException e) {
+            Log.e(TAG, "Unable to find or successfully query content provider, ignoring action", e);
+            return new ArrayList<>();
+        }
+
+        if (partnerSummaryActions == null || partnerSummaryActions.isEmpty()) {
+            Log.v(TAG, "No actions were fetched for partners");
+            return new ArrayList<>();
+        }
+
+        List<SummaryAction> summaryActionList = new ArrayList<>();
+        for (String actionId : partnerSummaryActions) {
+            Log.v(TAG, "Attempting to generate summary action for id: " + actionId);
+            try {
+                boolean completed =
+                        getActionCompletionStateFromContentProvider(actionId, mContentProviderUri);
+                Bundle summaryActionBundle =
+                        getActionSummaryStateFromContentProvider(actionId, mContentProviderUri);
+                SummaryAction summaryAction = buildSummaryAction(completed, summaryActionBundle);
+                if (summaryAction != null) {
+                    summaryActionList.add(summaryAction);
+                }
+            } catch (NullPointerException | IllegalArgumentException e) {
+                Log.e(
+                        TAG,
+                        "Unable to load the completion or config state for summary action: "
+                                + actionId,
+                        e);
+            }
+        }
+        return summaryActionList;
+    }
+
+    /** Returns the set of partner deferred actions provided by the partner content provider. */
+    public List<DeferredAction> getPartnerDeferredActions() {
+        if (mContentProviderUri == null) {
+            Log.e(TAG, "No content provider URI found, deferred actions ignored");
+            return new ArrayList<>();
+        }
+
+        ArrayList<String> partnerSummaryActions;
+        try {
+            partnerSummaryActions = getPartnerSummaryActionsFromContentProvider(
+                    mContentProviderUri);
+        } catch (NullPointerException | IllegalArgumentException e) {
+            Log.e(TAG, "Unable to find or successfully query content provider, ignoring action", e);
+            return new ArrayList<>();
+        }
+
+        if (partnerSummaryActions == null || partnerSummaryActions.isEmpty()) {
+            Log.v(TAG, "No actions were fetched for partners");
+            return new ArrayList<>();
+        }
+
+        List<DeferredAction> deferredActions = new ArrayList<>();
+        for (String actionId : partnerSummaryActions) {
+            Log.v(TAG, "Attempting to generate deferred action for id: " + actionId);
+            try {
+                boolean completed =
+                        getActionCompletionStateFromContentProvider(actionId, mContentProviderUri);
+                Bundle deferredActionBundle =
+                        getDeferredActionStateFromContentProvider(actionId, mContentProviderUri);
+                if (deferredActionBundle == null) {
+                    Log.v(TAG, "No valid deferredActionBundle for action: " + actionId);
+                    continue;
+                }
+                DeferredAction deferredAction = buildDeferredAction(completed,
+                        deferredActionBundle);
+                if (deferredAction != null) {
+                    deferredActions.add(deferredAction);
+                }
+            } catch (NullPointerException e) {
+                Log.e(
+                        TAG,
+                        "Unable to load the completion or config state for deferred action: "
+                                + actionId,
+                        e);
+            }
+        }
+        return deferredActions;
+    }
+
+    /**
+     * Gets the list of actionId's for the partner summary actions form the passed in content
+     * provider
+     * {@link Uri}.
+     *
+     * @throws NullPointerException     if the method is null on the content provider.
+     * @throws IllegalArgumentException if uri is not known or the request method is not supported
+     *                                  properly.
+     */
+    private ArrayList<String> getPartnerSummaryActionsFromContentProvider(Uri contentProviderUri) {
+        Bundle result = mContext.getContentResolver().call(
+                contentProviderUri,
+                METHOD_GET_SUMMARY_ACTIONS,
+                /* arg= */ null,
+                /* extras= */ null);
+        if (result == null || result.getStringArrayList(EXTRA_SUMMARY_ACTIONS_LIST) == null) {
+            Log.e(
+                    TAG,
+                    "No summary actions returned from content resolve call, can't fetch partner "
+                            + "actions.");
+            throw new IllegalArgumentException(
+                    "Uri: " + contentProviderUri + " did not return a list of actionId's.");
+        }
+        return result.getStringArrayList(EXTRA_SUMMARY_ACTIONS_LIST);
+    }
+
+    /**
+     * Gets the completion state for the specific actionId passed in using the passed in content
+     * provider {@link Uri}.
+     *
+     * @throws NullPointerException     if the method is null on the content provider.
+     * @throws IllegalArgumentException if uri is not known or the request method is not supported
+     *                                  properly.
+     */
+    private boolean getActionCompletionStateFromContentProvider(
+            String actionId, Uri contentProviderUri) {
+        Bundle completionStateArgs = new Bundle();
+        completionStateArgs.putString(EXTRA_ACTION_ID, actionId);
+        Bundle result = mContext.getContentResolver().call(
+                contentProviderUri,
+                METHOD_GET_ACTION_COMPLETION_STATE,
+                /* arg= */ null,
+                completionStateArgs);
+        if (result == null || !result.containsKey(EXTRA_IS_ACTION_COMPLETED)) {
+            throw new IllegalArgumentException(
+                    "No action with id " + actionId + " found in content provider");
+        }
+        return result.getBoolean(EXTRA_IS_ACTION_COMPLETED, true);
+    }
+
+    private Bundle getActionSummaryStateFromContentProvider(String actionId,
+            Uri contentProviderUri) {
+        Bundle summaryStateArgs = new Bundle();
+        summaryStateArgs.putString(EXTRA_ACTION_ID, actionId);
+        Bundle result = mContext.getContentResolver().call(
+                contentProviderUri,
+                METHOD_GET_ACTION_SUMMARY_STATE,
+                /* arg= */ null,
+                summaryStateArgs);
+        if (result == null) {
+            throw new IllegalArgumentException(
+                    "No action summary found in content provider for " + actionId);
+        }
+        return result;
+    }
+
+    private Bundle getDeferredActionStateFromContentProvider(String actionId,
+            Uri contentProviderUri) {
+        Bundle deferredStateArgs = new Bundle();
+        deferredStateArgs.putString(EXTRA_ACTION_ID, actionId);
+        Bundle result;
+        try {
+            result = mContext.getContentResolver().call(
+                    contentProviderUri,
+                    METHOD_GET_DEFERRED_ACTION_STATE,
+                    /* arg= */ null,
+                    deferredStateArgs);
+        } catch (UnsupportedOperationException e) {
+            Log.v(TAG, "Deferred notification query not supported by partner content provider");
+            return null;
+        }
+        return result;
+    }
+}
diff --git a/library/main/src/com/android/car/setupwizardlib/summary/SummaryAction.java b/library/main/src/com/android/car/setupwizardlib/summary/SummaryAction.java
new file mode 100644
index 0000000..aac4ce7
--- /dev/null
+++ b/library/main/src/com/android/car/setupwizardlib/summary/SummaryAction.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 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.android.car.setupwizardlib.summary;
+
+import android.annotation.NonNull;
+
+/** An instance that represents a single summary action item and all of its state. */
+public class SummaryAction implements Comparable<SummaryAction> {
+
+    public final String actionTitle;
+    public final String actionDescription;
+    public final boolean requiresNetwork;
+    public final String scriptUri;
+    public final int priority;
+    public final boolean hasUnfinishedDependency;
+    public final String dependencyDescription;
+    public final boolean completed;
+    public final String iconResourceName;
+    public final String completedDescription;
+
+    public SummaryAction(
+            String actionTitle,
+            String actionDescription,
+            boolean requiresNetwork,
+            boolean completed,
+            int priority,
+            String scriptUri,
+            boolean hasUnfinishedDependency,
+            String dependencyDescription,
+            String iconResourceName,
+            String completedDescription) {
+        this.actionTitle = actionTitle;
+        this.actionDescription = actionDescription;
+        this.requiresNetwork = requiresNetwork;
+        this.completed = completed;
+        this.priority = priority;
+        this.scriptUri = scriptUri;
+        this.hasUnfinishedDependency = hasUnfinishedDependency;
+        this.dependencyDescription = dependencyDescription;
+        this.iconResourceName = iconResourceName;
+        this.completedDescription = completedDescription;
+    }
+
+    @Override
+    public int compareTo(@NonNull SummaryAction o) {
+        if (o == null) {
+            return 1;
+        }
+        return priority - o.priority;
+    }
+}
diff --git a/library/main/src/com/android/car/setupwizardlib/util/CarDrivingStateMonitor.java b/library/main/src/com/android/car/setupwizardlib/util/CarDrivingStateMonitor.java
index 5408aa1..126f7e0 100644
--- a/library/main/src/com/android/car/setupwizardlib/util/CarDrivingStateMonitor.java
+++ b/library/main/src/com/android/car/setupwizardlib/util/CarDrivingStateMonitor.java
@@ -18,8 +18,12 @@
 
 import android.car.Car;
 import android.car.CarNotConnectedException;
+import android.car.VehicleAreaType;
+import android.car.VehiclePropertyIds;
 import android.car.drivingstate.CarUxRestrictions;
 import android.car.drivingstate.CarUxRestrictionsManager;
+import android.car.hardware.CarPropertyValue;
+import android.car.hardware.property.CarPropertyManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -42,11 +46,17 @@
     public static final String EXIT_BROADCAST_ACTION =
             "com.android.car.setupwizardlib.driving_exit";
 
+    public static final String INTENT_EXTRA_REASON = "reason";
+    public static final String REASON_GEAR_REVERSAL = "gear_reversal";
+
     private static final String TAG = "CarDrivingStateMonitor";
     private static final long DISCONNECT_DELAY_MS = 700;
 
+    private static final int GEAR_REVERSE = 2;
+
     private Car mCar;
     private CarUxRestrictionsManager mRestrictionsManager;
+    private CarPropertyManager mCarPropertyManager;
     // Need to track the number of times the monitor is started so a single stopMonitor call does
     // not override them all.
     private int mMonitorStartedCount;
@@ -60,6 +70,25 @@
     @VisibleForTesting
     final Runnable mDisconnectRunnable = this::disconnectCarMonitor;
 
+    private final CarPropertyManager.CarPropertyEventCallback mGearChangeCallback =
+            new CarPropertyManager.CarPropertyEventCallback() {
+        @SuppressWarnings("rawtypes")
+        @Override
+        public void onChangeEvent(CarPropertyValue value) {
+            switch (value.getPropertyId()) {
+                case VehiclePropertyIds.GEAR_SELECTION:
+                    if ((Integer) value.getValue() == GEAR_REVERSE) {
+                        Log.v(TAG, "Gear has reversed, exiting SetupWizard.");
+                        broadcastGearReversal();
+                    }
+                    break;
+            }
+        }
+
+        @Override
+        public void onErrorEvent(int propertyId, int zone) {}
+    };
+
     private CarDrivingStateMonitor(Context context) {
         mContext = context.getApplicationContext();
     }
@@ -107,18 +136,9 @@
             @Override
             public void onServiceConnected(ComponentName name, IBinder service) {
                 try {
-                    mRestrictionsManager = (CarUxRestrictionsManager)
-                            mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
-                    if (mRestrictionsManager == null) {
-                        Log.e(TAG, "Unable to get CarUxRestrictionsManager");
-                        return;
-                    }
-                    onUxRestrictionsChanged(mRestrictionsManager.getCurrentCarUxRestrictions());
-                    mRestrictionsManager.registerListener(CarDrivingStateMonitor.this);
-                    if (mStopMonitorAfterUxCheck) {
-                        mStopMonitorAfterUxCheck = false;
-                        stopMonitor();
-                    }
+                    registerPropertyManager();
+                    registerRestrictionsManager();
+
                 } catch (CarNotConnectedException e) {
                     Log.e(TAG, "Car not connected", e);
                 }
@@ -179,6 +199,10 @@
                 mRestrictionsManager.unregisterListener();
                 mRestrictionsManager = null;
             }
+            if (mCarPropertyManager != null) {
+                mCarPropertyManager.unregisterCallback(mGearChangeCallback);
+                mCarPropertyManager = null;
+            }
         } catch (CarNotConnectedException e) {
             Log.e(TAG, "Car not connected for unregistering listener", e);
         }
@@ -267,4 +291,50 @@
         CarHelperRegistry.getRegistry(context).putHelper(
                 CarDrivingStateMonitor.class, new CarDrivingStateMonitor(context));
     }
+
+    private void registerRestrictionsManager() {
+        mRestrictionsManager = (CarUxRestrictionsManager)
+                mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
+        if (mRestrictionsManager == null) {
+            Log.e(TAG, "Unable to get CarUxRestrictionsManager");
+            return;
+        }
+        onUxRestrictionsChanged(mRestrictionsManager.getCurrentCarUxRestrictions());
+        mRestrictionsManager.registerListener(CarDrivingStateMonitor.this);
+        if (mStopMonitorAfterUxCheck) {
+            mStopMonitorAfterUxCheck = false;
+            stopMonitor();
+        }
+    }
+
+    private void registerPropertyManager() {
+        mCarPropertyManager = (CarPropertyManager) mCar.getCarManager(Car.PROPERTY_SERVICE);
+        if (mCarPropertyManager == null) {
+            Log.e(TAG, "Unable to get CarPropertyManager");
+            return;
+        }
+        mCarPropertyManager.registerCallback(
+                mGearChangeCallback, VehiclePropertyIds.GEAR_SELECTION,
+                CarPropertyManager.SENSOR_RATE_ONCHANGE);
+        CarPropertyValue<Integer> gearSelection =
+                mCarPropertyManager.getProperty(Integer.class, VehiclePropertyIds.GEAR_SELECTION,
+                    VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
+        if (gearSelection != null
+                && gearSelection.getStatus() == CarPropertyValue.STATUS_AVAILABLE) {
+            if (gearSelection.getValue() == GEAR_REVERSE) {
+                Log.v(TAG, "SetupWizard started when gear is in reverse, exiting.");
+                broadcastGearReversal();
+            }
+        } else {
+            Log.e(TAG, "GEAR_SELECTION is not available.");
+        }
+    }
+
+    private void broadcastGearReversal() {
+        Intent intent = new Intent();
+        intent.setAction(EXIT_BROADCAST_ACTION);
+        intent.putExtra(INTENT_EXTRA_REASON, REASON_GEAR_REVERSAL);
+        mContext.sendBroadcast(intent);
+    }
+
 }
diff --git a/library/main/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtils.java b/library/main/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtils.java
index 5a87323..3af842a 100644
--- a/library/main/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtils.java
+++ b/library/main/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtils.java
@@ -17,33 +17,26 @@
 package com.android.car.setupwizardlib.util;
 
 import android.app.Activity;
-import android.util.Log;
 import android.view.View;
 
 import androidx.core.util.Preconditions;
 
-import com.android.car.setupwizardlib.partner.PartnerConfig;
-import com.android.car.setupwizardlib.partner.PartnerConfigHelper;
-
 /** Utilities to aid in UI for car setup wizard flow. */
 public final class CarSetupWizardUiUtils {
     private static final String TAG = CarSetupWizardUiUtils.class.getSimpleName();
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
 
-    /** Hide system UI if configured as such by partner */
+    /** Hide system UI */
+    public static void hideSystemUI(Activity activity) {
+        maybeHideSystemUI(activity);
+    }
+
+    /** Hide system UI
+     * @deprecated Use {@code hideSystemUI}
+     **/
+    @Deprecated
     public static void maybeHideSystemUI(Activity activity) {
         Preconditions.checkNotNull(activity);
 
-        if (!PartnerConfigHelper.get(activity)
-                .getBoolean(activity, PartnerConfig.CONFIG_IS_IMMERSIVE, true)) {
-            if (VERBOSE) {
-                Log.v(TAG, "Immersive mode disabled");
-            }
-            return;
-        }
-        if (VERBOSE) {
-            Log.v(TAG, "Setting immersive mode for SystemUi");
-        }
         // See https://developer.android.com/training/system-ui/immersive#EnableFullscreen
         // Enables regular immersive mode.
         // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
diff --git a/library/main/tests/robotests/src/com/android/car/setupwizardlib/CarSetupWizardCompatLayoutTest.java b/library/main/tests/robotests/src/com/android/car/setupwizardlib/CarSetupWizardCompatLayoutTest.java
index 2ec9db8..6ec0c28 100644
--- a/library/main/tests/robotests/src/com/android/car/setupwizardlib/CarSetupWizardCompatLayoutTest.java
+++ b/library/main/tests/robotests/src/com/android/car/setupwizardlib/CarSetupWizardCompatLayoutTest.java
@@ -440,18 +440,6 @@
     }
 
     @Test
-    public void testTitleBarElevationChange() {
-        mCarSetupWizardCompatLayout.addElevationToTitleBar(/*animate= */ false);
-        View titleBar = mCarSetupWizardCompatLayout.findViewById(R.id.application_bar);
-        assertThat(titleBar.getElevation()).isEqualTo(
-                application.getResources().getDimension(
-                        R.dimen.title_bar_drop_shadow_elevation));
-
-        mCarSetupWizardCompatLayout.removeElevationFromTitleBar(/*animate= */ false);
-        assertThat(titleBar.getElevation()).isEqualTo(0f);
-    }
-
-    @Test
     public void testPartnerResourcesAreApplied() {
         setupFakeContentProvider();