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 android.content.Context;
19 import android.content.res.ColorStateList;
20 import android.content.res.Configuration;
21 import android.content.res.TypedArray;
22 import android.graphics.drawable.Drawable;
23 import android.graphics.drawable.RippleDrawable;
24 import android.graphics.drawable.VectorDrawable;
25 import android.util.AttributeSet;
26 import android.view.MotionEvent;
27 
28 import androidx.annotation.Nullable;
29 
30 /**
31  * Similar to the {@link NumPadKey}, but displays an image.
32  */
33 public class NumPadButton extends AlphaOptimizedImageButton {
34 
35     @Nullable
36     private NumPadAnimator mAnimator;
37     private int mOrientation;
38 
NumPadButton(Context context, AttributeSet attrs)39     public NumPadButton(Context context, AttributeSet attrs) {
40         super(context, attrs);
41 
42         Drawable background = getBackground();
43         if (background instanceof RippleDrawable) {
44             mAnimator = new NumPadAnimator(context, (RippleDrawable) getBackground(),
45                     attrs.getStyleAttribute());
46         } else {
47             mAnimator = null;
48         }
49     }
50 
51     @Override
onConfigurationChanged(Configuration newConfig)52     protected void onConfigurationChanged(Configuration newConfig) {
53         mOrientation = newConfig.orientation;
54     }
55 
56     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)57     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
58         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
59 
60         // Set width/height to the same value to ensure a smooth circle for the bg, but shrink
61         // the height to match the old pin bouncer.
62         // This is only used for PIN/PUK; the main PIN pad now uses ConstraintLayout, which will
63         // force our width/height to conform to the ratio in the layout.
64         int width = getMeasuredWidth();
65 
66         boolean shortenHeight = mAnimator == null
67                 || mOrientation == Configuration.ORIENTATION_LANDSCAPE;
68         int height = shortenHeight ? (int) (width * .66f) : width;
69 
70         setMeasuredDimension(getMeasuredWidth(), height);
71     }
72 
73     @Override
onLayout(boolean changed, int l, int t, int r, int b)74     protected void onLayout(boolean changed, int l, int t, int r, int b) {
75         super.onLayout(changed, l, t, r, b);
76 
77         if (mAnimator != null) mAnimator.onLayout(b - t);
78     }
79 
80     @Override
onTouchEvent(MotionEvent event)81     public boolean onTouchEvent(MotionEvent event) {
82         if (event.getActionMasked() == MotionEvent.ACTION_DOWN && mAnimator != null) {
83             mAnimator.start();
84         }
85         return super.onTouchEvent(event);
86     }
87 
88     /**
89      * Reload colors from resources.
90      **/
reloadColors()91     public void reloadColors() {
92         if (mAnimator != null) mAnimator.reloadColors(getContext());
93 
94         int[] customAttrs = {android.R.attr.textColorPrimaryInverse};
95         TypedArray a = getContext().obtainStyledAttributes(customAttrs);
96         int imageColor = a.getColor(0, 0);
97         a.recycle();
98         ((VectorDrawable) getDrawable()).setTintList(ColorStateList.valueOf(imageColor));
99     }
100 }
101