• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.graphics.drawable.Drawable;
22 import android.graphics.drawable.GradientDrawable;
23 import android.graphics.drawable.VectorDrawable;
24 import android.util.AttributeSet;
25 import android.view.MotionEvent;
26 import android.view.accessibility.AccessibilityNodeInfo;
27 
28 import androidx.annotation.DrawableRes;
29 import androidx.annotation.Nullable;
30 
31 import com.android.systemui.Flags;
32 import com.android.systemui.bouncer.shared.constants.PinBouncerConstants.Color;
33 import com.android.systemui.res.R;
34 
35 /**
36  * Similar to the {@link NumPadKey}, but displays an image.
37  */
38 public class NumPadButton extends AlphaOptimizedImageButton implements NumPadAnimationListener {
39 
40     @Nullable
41     private NumPadAnimator mAnimator;
42     private int mOrientation;
43     private int mStyleAttr;
44     private boolean mIsTransparentMode;
45 
46     @DrawableRes
47     private int mDrawableForTransparentMode = 0;
48 
49     @DrawableRes
50     private int mDefaultDrawable = 0;
51 
NumPadButton(Context context, AttributeSet attrs)52     public NumPadButton(Context context, AttributeSet attrs) {
53         super(context, attrs);
54         mStyleAttr = attrs.getStyleAttribute();
55         setupAnimator();
56     }
57 
58     @Override
onConfigurationChanged(Configuration newConfig)59     protected void onConfigurationChanged(Configuration newConfig) {
60         mOrientation = newConfig.orientation;
61     }
62 
63     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)64     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
65         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
66 
67         // Set width/height to the same value to ensure a smooth circle for the bg, but shrink
68         // the height to match the old pin bouncer.
69         // This is only used for PIN/PUK; the main PIN pad now uses ConstraintLayout, which will
70         // force our width/height to conform to the ratio in the layout.
71         int width = getMeasuredWidth();
72 
73         boolean shortenHeight = mAnimator == null
74                 || mOrientation == Configuration.ORIENTATION_LANDSCAPE;
75         int height = shortenHeight ? (int) (width * .66f) : width;
76 
77         setMeasuredDimension(getMeasuredWidth(), height);
78     }
79 
80     @Override
onLayout(boolean changed, int l, int t, int r, int b)81     protected void onLayout(boolean changed, int l, int t, int r, int b) {
82         super.onLayout(changed, l, t, r, b);
83         int width = r - l;
84         int height = b - t;
85         if (mAnimator != null) mAnimator.onLayout(width, height);
86     }
87 
88     @Override
onTouchEvent(MotionEvent event)89     public boolean onTouchEvent(MotionEvent event) {
90         switch(event.getActionMasked()) {
91             case MotionEvent.ACTION_DOWN:
92                 if (mAnimator != null) mAnimator.expand();
93                 break;
94             case MotionEvent.ACTION_UP:
95             case MotionEvent.ACTION_CANCEL:
96                 if (mAnimator != null) mAnimator.contract();
97                 break;
98         }
99         return super.onTouchEvent(event);
100     }
101 
102     /**
103      * Reload colors from resources.
104      **/
reloadColors()105     public void reloadColors() {
106         if (mAnimator != null) mAnimator.reloadColors(getContext());
107 
108         int textColorResId = mIsTransparentMode ? Color.actionWithAutoConfirm : Color.action;
109         int imageColor = getContext().getColor(textColorResId);
110         ((VectorDrawable) getDrawable()).setTintList(ColorStateList.valueOf(imageColor));
111     }
112 
113     @Override
setProgress(float progress)114     public void setProgress(float progress) {
115         if (mAnimator != null) {
116             mAnimator.setProgress(progress);
117         }
118     }
119 
120     /**
121      * Set whether button is transparent mode.
122      *
123      * @param isTransparentMode
124      */
setTransparentMode(boolean isTransparentMode)125     public void setTransparentMode(boolean isTransparentMode) {
126         if (mIsTransparentMode == isTransparentMode) {
127             return;
128         }
129 
130         mIsTransparentMode = isTransparentMode;
131 
132         if (isTransparentMode) {
133             if (mDrawableForTransparentMode != 0) {
134                 setImageResource(mDrawableForTransparentMode);
135             }
136             setBackgroundColor(getResources().getColor(android.R.color.transparent));
137         } else {
138             if (mDefaultDrawable != 0) {
139                 setImageResource(mDefaultDrawable);
140             }
141             Drawable bgDrawable = getContext().getDrawable(R.drawable.num_pad_key_background);
142             if (Flags.bouncerUiRevamp2() && bgDrawable != null) {
143                 bgDrawable.setTint(Color.actionBg);
144             }
145             setBackground(bgDrawable);
146         }
147         setupAnimator();
148         reloadColors();
149         requestLayout();
150     }
151 
152     /**
153      * Set up the animator for the NumPadButton.
154      */
setupAnimator()155     private void setupAnimator() {
156         Drawable background = getBackground();
157         if (background instanceof GradientDrawable) {
158             mAnimator = new NumPadAnimator(getContext(), background.mutate(),
159                     mStyleAttr, getDrawable());
160         } else {
161             mAnimator = null;
162         }
163     }
164 
165     @Override
onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info)166     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
167         super.onInitializeAccessibilityNodeInfo(info);
168         info.setTextEntryKey(true);
169     }
170 
171     /**
172      * Drawable to use when transparent mode is enabled
173      */
setDrawableForTransparentMode(@rawableRes int drawableResId)174     public void setDrawableForTransparentMode(@DrawableRes int drawableResId) {
175         mDrawableForTransparentMode = drawableResId;
176     }
177 
178     /**
179      * Drawable to use when transparent mode is not enabled.
180      */
setDefaultDrawable(@rawableRes int drawableResId)181     public void setDefaultDrawable(@DrawableRes int drawableResId) {
182         mDefaultDrawable = drawableResId;
183         setImageResource(mDefaultDrawable);
184     }
185 }
186