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
This commit is contained in:
Chandru S
2023-04-25 12:11:27 -07:00
parent 646ad05577
commit cd933eedb3
15 changed files with 192 additions and 14 deletions

View File

@@ -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>

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -22,8 +22,6 @@ import android.animation.AnimatorSet
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 @@ open class BouncerKeyguardMessageArea(context: Context?, attrs: AttributeSet?) :
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 @@ open class BouncerKeyguardMessageArea(context: Context?, attrs: AttributeSet?) :
}
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()
}

View File

@@ -22,6 +22,8 @@ import android.view.HapticFeedbackConstants;
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 @@ public abstract class KeyguardAbsKeyInputView extends KeyguardInputView {
protected abstract void resetState();
@Override
@CallSuper
protected void onFinishInflate() {
super.onFinishInflate();
mEcaView = findViewById(R.id.keyguard_selector_fade_container);
}

View File

@@ -21,11 +21,14 @@ import android.animation.AnimatorListenerAdapter;
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 @@ import com.android.internal.jank.InteractionJankMonitor;
public abstract class KeyguardInputView extends LinearLayout {
private Runnable mOnFinishImeAnimationRunnable;
@Nullable
private View mBouncerMessageView;
public KeyguardInputView(Context context) {
super(context);
}
@@ -87,6 +93,18 @@ public abstract class KeyguardInputView extends LinearLayout {
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();

View File

@@ -44,11 +44,17 @@ public abstract class KeyguardMessageArea extends TextView implements SecurityMe
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 @@ public abstract class KeyguardMessageArea extends TextView implements SecurityMe
}
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)) {

View File

@@ -51,7 +51,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
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 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
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 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
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];

View File

@@ -34,6 +34,8 @@ import android.util.AttributeSet;
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 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView
}
@Override
@CallSuper
protected void onFinishInflate() {
super.onFinishInflate();
mPasswordEntry = findViewById(getPasswordTextViewId());
// Set selected property on so the view can send accessibility events.

View File

@@ -30,6 +30,7 @@ abstract class KeyguardSimInputView(context: Context, attrs: AttributeSet) :
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()

View File

@@ -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()
}
}