1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.keyguard; 17 18 import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BUTTON; 19 import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY; 20 21 import android.content.Context; 22 import android.content.res.ColorStateList; 23 import android.content.res.Configuration; 24 import android.graphics.drawable.Drawable; 25 import android.graphics.drawable.GradientDrawable; 26 import android.graphics.drawable.VectorDrawable; 27 import android.util.AttributeSet; 28 import android.view.MotionEvent; 29 import android.view.accessibility.AccessibilityNodeInfo; 30 31 import androidx.annotation.Nullable; 32 33 import com.android.settingslib.Utils; 34 import com.android.systemui.res.R; 35 36 /** 37 * Similar to the {@link NumPadKey}, but displays an image. 38 */ 39 public class NumPadButton extends AlphaOptimizedImageButton implements NumPadAnimationListener { 40 41 @Nullable 42 private NumPadAnimator mAnimator; 43 private int mOrientation; 44 private int mStyleAttr; 45 private boolean mIsTransparentMode; 46 NumPadButton(Context context, AttributeSet attrs)47 public NumPadButton(Context context, AttributeSet attrs) { 48 super(context, attrs); 49 mStyleAttr = attrs.getStyleAttribute(); 50 setupAnimator(); 51 } 52 53 @Override onConfigurationChanged(Configuration newConfig)54 protected void onConfigurationChanged(Configuration newConfig) { 55 mOrientation = newConfig.orientation; 56 } 57 58 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)59 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 60 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 61 62 // Set width/height to the same value to ensure a smooth circle for the bg, but shrink 63 // the height to match the old pin bouncer. 64 // This is only used for PIN/PUK; the main PIN pad now uses ConstraintLayout, which will 65 // force our width/height to conform to the ratio in the layout. 66 int width = getMeasuredWidth(); 67 68 boolean shortenHeight = mAnimator == null 69 || mOrientation == Configuration.ORIENTATION_LANDSCAPE; 70 int height = shortenHeight ? (int) (width * .66f) : width; 71 72 setMeasuredDimension(getMeasuredWidth(), height); 73 } 74 75 @Override onLayout(boolean changed, int l, int t, int r, int b)76 protected void onLayout(boolean changed, int l, int t, int r, int b) { 77 super.onLayout(changed, l, t, r, b); 78 int width = r - l; 79 int height = b - t; 80 if (mAnimator != null) mAnimator.onLayout(width, height); 81 } 82 83 @Override onTouchEvent(MotionEvent event)84 public boolean onTouchEvent(MotionEvent event) { 85 switch(event.getActionMasked()) { 86 case MotionEvent.ACTION_DOWN: 87 if (mAnimator != null) mAnimator.expand(); 88 break; 89 case MotionEvent.ACTION_UP: 90 case MotionEvent.ACTION_CANCEL: 91 if (mAnimator != null) mAnimator.contract(); 92 break; 93 } 94 return super.onTouchEvent(event); 95 } 96 97 /** 98 * Reload colors from resources. 99 **/ reloadColors()100 public void reloadColors() { 101 if (mAnimator != null) mAnimator.reloadColors(getContext()); 102 103 int textColorResId = mIsTransparentMode ? NUM_PAD_KEY : NUM_PAD_BUTTON; 104 int imageColor = Utils.getColorAttrDefaultColor(getContext(), textColorResId); 105 ((VectorDrawable) getDrawable()).setTintList(ColorStateList.valueOf(imageColor)); 106 } 107 108 @Override setProgress(float progress)109 public void setProgress(float progress) { 110 if (mAnimator != null) { 111 mAnimator.setProgress(progress); 112 } 113 } 114 115 /** 116 * Set whether button is transparent mode. 117 * 118 * @param isTransparentMode 119 */ setTransparentMode(boolean isTransparentMode)120 public void setTransparentMode(boolean isTransparentMode) { 121 if (mIsTransparentMode == isTransparentMode) { 122 return; 123 } 124 125 mIsTransparentMode = isTransparentMode; 126 127 if (isTransparentMode) { 128 setBackgroundColor(getResources().getColor(android.R.color.transparent)); 129 } else { 130 setBackground(getContext().getDrawable(R.drawable.num_pad_key_background)); 131 } 132 setupAnimator(); 133 reloadColors(); 134 requestLayout(); 135 } 136 137 /** 138 * Set up the animator for the NumPadButton. 139 */ setupAnimator()140 private void setupAnimator() { 141 Drawable background = getBackground(); 142 if (background instanceof GradientDrawable) { 143 mAnimator = new NumPadAnimator(getContext(), background.mutate(), 144 mStyleAttr, getDrawable()); 145 } else { 146 mAnimator = null; 147 } 148 } 149 150 @Override onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info)151 public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 152 super.onInitializeAccessibilityNodeInfo(info); 153 info.setTextEntryKey(true); 154 } 155 } 156