Add views for displaying the new bouncer messages

Other changes:
 - Provide API to access the view and initialize it from a view binder.
 - Changes conflicting field name in subclasses of KeyguardInputView

Bug: 275600559
Test: NA, only view changes

Change-Id: Ifbba196068be7e08b4a3da1d864b60ea9a16414a
diff --git a/packages/SystemUI/res-keyguard/layout/bouncer_message_view.xml b/packages/SystemUI/res-keyguard/layout/bouncer_message_view.xml
new file mode 100644
index 0000000..f7dac13
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/bouncer_message_view.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2023 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
+  -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <com.android.keyguard.BouncerKeyguardMessageArea
+        android:id="@+id/bouncer_primary_message_area"
+        style="@style/Keyguard.Bouncer.PrimaryMessage"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/keyguard_lock_padding"
+        android:focusable="true"
+         />
+
+    <com.android.keyguard.BouncerKeyguardMessageArea
+        android:id="@+id/bouncer_secondary_message_area"
+        style="@style/Keyguard.Bouncer.SecondaryMessage"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/secondary_message_padding"
+        android:focusable="true" />
+
+</merge>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
index 6ec65ce..3412a30 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
@@ -29,6 +29,13 @@
     >
     <include layout="@layout/keyguard_bouncer_message_area"/>
 
+    <com.android.systemui.keyguard.bouncer.ui.BouncerMessageView
+        android:id="@+id/bouncer_message_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+    />
+
     <Space
         android:layout_width="match_parent"
         android:layout_height="0dp"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
index c772c96..78a7c17 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
@@ -33,6 +33,12 @@
     android:clipToPadding="false">
     <include layout="@layout/keyguard_bouncer_message_area"/>
 
+    <com.android.systemui.keyguard.bouncer.ui.BouncerMessageView
+        android:id="@+id/bouncer_message_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" />
+
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/pattern_container"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index f61df05..330676b 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -29,6 +29,12 @@
     androidprv:layout_maxWidth="@dimen/keyguard_security_width">
 <include layout="@layout/keyguard_bouncer_message_area"/>
 
+<com.android.systemui.keyguard.bouncer.ui.BouncerMessageView
+    android:id="@+id/bouncer_message_view"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical" />
+
 <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/pin_container"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 4d289eb..88f7bcd 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -23,6 +23,26 @@
     <style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView">
         <item name="android:textSize">@dimen/kg_status_line_font_size</item>
         <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
+        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+    </style>
+    <style name="Keyguard.Bouncer.PrimaryMessage" parent="Theme.SystemUI">
+        <item name="android:textSize">18sp</item>
+        <item name="android:lineHeight">24dp</item>
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:singleLine">true</item>
+        <item name="android:textAlignment">center</item>
+        <item name="android:ellipsize">marquee</item>
+    </style>
+    <style name="Keyguard.Bouncer.SecondaryMessage" parent="Theme.SystemUI">
+        <item name="android:textSize">14sp</item>
+        <item name="android:lineHeight">20dp</item>
+        <item name="android:maxLines">@integer/bouncer_secondary_message_lines</item>
+        <item name="android:lines">@integer/bouncer_secondary_message_lines</item>
+        <item name="android:textAlignment">center</item>
+        <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
+        <item name="android:ellipsize">end</item>
+        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
     </style>
     <style name="Keyguard.TextView.EmergencyButton" parent="Theme.SystemUI">
         <item name="android:textColor">?androidprv:attr/materialColorOnTertiaryFixed</item>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 26d6875..b4e1b66 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -577,6 +577,9 @@
     <!-- Whether to show the side fps hint while on bouncer -->
     <bool name="config_show_sidefps_hint_on_bouncer">true</bool>
 
+    <!-- Max number of lines we want to show for the bouncer secondary message -->
+    <integer name="bouncer_secondary_message_lines">2</integer>
+
     <!-- Whether to use the split 2-column notification shade -->
     <bool name="config_use_split_notification_shade">false</bool>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 2024dae..60348ff 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -807,6 +807,7 @@
     <!-- The width/height of the unlock icon view on keyguard. -->
     <dimen name="keyguard_lock_height">42dp</dimen>
     <dimen name="keyguard_lock_padding">20dp</dimen>
+    <dimen name="secondary_message_padding">8dp</dimen>
 
     <dimen name="keyguard_security_container_padding_top">20dp</dimen>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
index a82f0e3..0842953 100644
--- a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
+++ b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
@@ -22,8 +22,6 @@
 import android.animation.ObjectAnimator
 import android.content.Context
 import android.content.res.ColorStateList
-import android.content.res.TypedArray
-import android.graphics.Color
 import android.util.AttributeSet
 import android.view.View
 import com.android.app.animation.Interpolators
@@ -41,12 +39,28 @@
     protected open val SHOW_DURATION_MILLIS = 150L
     protected open val HIDE_DURATION_MILLIS = 200L
 
+    override fun onFinishInflate() {
+        super.onFinishInflate()
+        mDefaultColorState = getColorInStyle()
+    }
+
+    private fun getColorInStyle(): ColorStateList? {
+        val styledAttributes =
+            context.obtainStyledAttributes(styleResId, intArrayOf(android.R.attr.textColor))
+        var colorStateList: ColorStateList? = null
+        if (styledAttributes != null) {
+            colorStateList = styledAttributes.getColorStateList(0)
+        }
+        styledAttributes.recycle()
+        return colorStateList
+    }
+
     override fun updateTextColor() {
         var colorState = mDefaultColorState
         mNextMessageColorState?.defaultColor?.let { color ->
             if (color != DEFAULT_COLOR) {
                 colorState = mNextMessageColorState
-                mNextMessageColorState = ColorStateList.valueOf(DEFAULT_COLOR)
+                mNextMessageColorState = mDefaultColorState ?: ColorStateList.valueOf(DEFAULT_COLOR)
             }
         }
         setTextColor(colorState)
@@ -57,15 +71,12 @@
     }
 
     override fun onThemeChanged() {
-        val array: TypedArray = mContext.obtainStyledAttributes(intArrayOf(TITLE))
-        val newTextColors: ColorStateList = ColorStateList.valueOf(array.getColor(0, Color.RED))
-        array.recycle()
-        mDefaultColorState = newTextColors
+        mDefaultColorState = getColorInStyle() ?: Utils.getColorAttr(context, TITLE)
         super.onThemeChanged()
     }
 
     override fun reloadColor() {
-        mDefaultColorState = Utils.getColorAttr(context, TITLE)
+        mDefaultColorState = getColorInStyle() ?: Utils.getColorAttr(context, TITLE)
         super.reloadColor()
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index b18abf3..c6d1471 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -22,6 +22,8 @@
 import android.view.KeyEvent;
 import android.view.View;
 
+import androidx.annotation.CallSuper;
+
 import com.android.internal.widget.LockscreenCredential;
 import com.android.systemui.R;
 
@@ -48,7 +50,9 @@
     protected abstract void resetState();
 
     @Override
+    @CallSuper
     protected void onFinishInflate() {
+        super.onFinishInflate();
         mEcaView = findViewById(R.id.keyguard_selector_fade_container);
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java
index 7eae729..c9d9069 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java
@@ -21,11 +21,14 @@
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
+import android.view.View;
 import android.widget.LinearLayout;
 
+import androidx.annotation.CallSuper;
 import androidx.annotation.Nullable;
 
 import com.android.internal.jank.InteractionJankMonitor;
+import com.android.systemui.R;
 
 /**
  * A Base class for all Keyguard password/pattern/pin related inputs.
@@ -33,6 +36,9 @@
 public abstract class KeyguardInputView extends LinearLayout {
     private Runnable mOnFinishImeAnimationRunnable;
 
+    @Nullable
+    private View mBouncerMessageView;
+
     public KeyguardInputView(Context context) {
         super(context);
     }
@@ -87,6 +93,18 @@
         mOnFinishImeAnimationRunnable = onFinishImeAnimationRunnable;
     }
 
+    @Override
+    @CallSuper
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mBouncerMessageView = findViewById(R.id.bouncer_message_view);
+    }
+
+    @Nullable
+    public final View getBouncerMessageView() {
+        return mBouncerMessageView;
+    }
+
     public void runOnFinishImeAnimationRunnable() {
         if (mOnFinishImeAnimationRunnable != null) {
             mOnFinishImeAnimationRunnable.run();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
index 553453d..b01aed9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
@@ -44,11 +44,17 @@
     private ViewGroup mContainer;
     private int mTopMargin;
     protected boolean mAnimate;
+    private final int mStyleResId;
 
     public KeyguardMessageArea(Context context, AttributeSet attrs) {
         super(context, attrs);
         setLayerType(LAYER_TYPE_HARDWARE, null); // work around nested unclipped SaveLayer bug
-
+        if (attrs != null) {
+            mStyleResId = attrs.getStyleAttribute();
+        } else {
+            // Set to default reference style if the component is used without setting "style" attr
+            mStyleResId = R.style.Keyguard_TextView;
+        }
         onThemeChanged();
     }
 
@@ -82,13 +88,17 @@
     }
 
     void onDensityOrFontScaleChanged() {
-        TypedArray array = mContext.obtainStyledAttributes(R.style.Keyguard_TextView, new int[] {
+        TypedArray array = mContext.obtainStyledAttributes(getStyleResId(), new int[] {
                 android.R.attr.textSize
         });
         setTextSize(TypedValue.COMPLEX_UNIT_PX, array.getDimensionPixelSize(0, 0));
         array.recycle();
     }
 
+    protected int getStyleResId() {
+        return mStyleResId;
+    }
+
     @Override
     public void setMessage(CharSequence msg, boolean animate) {
         if (!TextUtils.isEmpty(msg)) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index 58807e4..2377057 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -51,7 +51,7 @@
     private View[][] mViews;
     private int mYTrans;
     private int mYTransOffset;
-    private View mBouncerMessageView;
+    private View mBouncerMessageArea;
     @DevicePostureInt private int mLastDevicePosture = DEVICE_POSTURE_UNKNOWN;
     public static final long ANIMATION_DURATION = 650;
 
@@ -145,7 +145,7 @@
         super.onFinishInflate();
 
         mContainer = findViewById(R.id.pin_container);
-        mBouncerMessageView = findViewById(R.id.bouncer_message_area);
+        mBouncerMessageArea = findViewById(R.id.bouncer_message_area);
         mViews = new View[][]{
                 new View[]{
                         findViewById(R.id.row0), null, null
@@ -221,9 +221,9 @@
         Interpolator legacyDecelerate = Interpolators.LEGACY_DECELERATE;
         float standardProgress = standardDecelerate.getInterpolation(progress);
 
-        mBouncerMessageView.setTranslationY(
+        mBouncerMessageArea.setTranslationY(
                 mYTrans - mYTrans * standardProgress);
-        mBouncerMessageView.setAlpha(standardProgress);
+        mBouncerMessageArea.setAlpha(standardProgress);
 
         for (int i = 0; i < mViews.length; i++) {
             View[] row = mViews[i];
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index b4ddc9a..d8e46c8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -34,6 +34,8 @@
 import android.view.KeyEvent;
 import android.view.View;
 
+import androidx.annotation.CallSuper;
+
 import com.android.app.animation.Interpolators;
 import com.android.internal.widget.LockscreenCredential;
 import com.android.systemui.R;
@@ -150,7 +152,9 @@
     }
 
     @Override
+    @CallSuper
     protected void onFinishInflate() {
+        super.onFinishInflate();
         mPasswordEntry = findViewById(getPasswordTextViewId());
 
         // Set selected property on so the view can send accessibility events.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
index 3fc39af..1461dbe 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
@@ -30,6 +30,7 @@
     private var disableESimButton: KeyguardEsimArea? = null
 
     override fun onFinishInflate() {
+        super.onFinishInflate()
         simImageView = findViewById(R.id.keyguard_sim)
         disableESimButton = findViewById(R.id.keyguard_esim_area)
         super.onFinishInflate()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/ui/BouncerMessageView.kt b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/ui/BouncerMessageView.kt
new file mode 100644
index 0000000..c0a5a51
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/ui/BouncerMessageView.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 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.systemui.keyguard.bouncer.ui
+
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.LinearLayout
+import com.android.keyguard.BouncerKeyguardMessageArea
+import com.android.keyguard.KeyguardMessageArea
+import com.android.keyguard.KeyguardMessageAreaController
+import com.android.systemui.R
+
+class BouncerMessageView : LinearLayout {
+    constructor(context: Context?) : super(context)
+
+    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
+
+    init {
+        inflate(context, R.layout.bouncer_message_view, this)
+    }
+
+    var primaryMessageView: BouncerKeyguardMessageArea? = null
+    var secondaryMessageView: BouncerKeyguardMessageArea? = null
+    var primaryMessage: KeyguardMessageAreaController<KeyguardMessageArea>? = null
+    var secondaryMessage: KeyguardMessageAreaController<KeyguardMessageArea>? = null
+    override fun onFinishInflate() {
+        super.onFinishInflate()
+        primaryMessageView = findViewById(R.id.bouncer_primary_message_area)
+        secondaryMessageView = findViewById(R.id.bouncer_secondary_message_area)
+    }
+
+    fun init(factory: KeyguardMessageAreaController.Factory) {
+        primaryMessage = factory.create(primaryMessageView)
+        primaryMessage?.init()
+        secondaryMessage = factory.create(secondaryMessageView)
+        secondaryMessage?.init()
+    }
+}