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