blob: fdde402965114a4547cb1cf3918cdd50f05bcc9f [file] [log] [blame]
/*
* Copyright (C) 2020 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.keyguard;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
import com.android.settingslib.Utils;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import java.io.PrintWriter;
/**
* A view positioned under the notification shade.
*/
public class LockIconView extends FrameLayout implements Dumpable {
@IntDef({ICON_NONE, ICON_LOCK, ICON_FINGERPRINT, ICON_UNLOCK})
public @interface IconType {}
public static final int ICON_NONE = -1;
public static final int ICON_LOCK = 0;
public static final int ICON_FINGERPRINT = 1;
public static final int ICON_UNLOCK = 2;
private @IconType int mIconType;
private boolean mAod;
@NonNull private final RectF mSensorRect;
@NonNull private PointF mLockIconCenter = new PointF(0f, 0f);
private float mRadius;
private int mLockIconPadding;
private ImageView mLockIcon;
private ImageView mBgView;
private int mLockIconColor;
private boolean mUseBackground = false;
private float mDozeAmount = 0f;
public LockIconView(Context context, AttributeSet attrs) {
super(context, attrs);
mSensorRect = new RectF();
}
@Override
public void onFinishInflate() {
super.onFinishInflate();
mLockIcon = findViewById(R.id.lock_icon);
mBgView = findViewById(R.id.lock_icon_bg);
}
void setDozeAmount(float dozeAmount) {
mDozeAmount = dozeAmount;
updateColorAndBackgroundVisibility();
}
void updateColorAndBackgroundVisibility() {
if (mUseBackground && mLockIcon.getDrawable() != null) {
mLockIconColor = ColorUtils.blendARGB(
Utils.getColorAttrDefaultColor(getContext(), android.R.attr.textColorPrimary),
Color.WHITE,
mDozeAmount);
mBgView.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg));
mBgView.setAlpha(1f - mDozeAmount);
mBgView.setVisibility(View.VISIBLE);
} else {
mLockIconColor = ColorUtils.blendARGB(
Utils.getColorAttrDefaultColor(getContext(), R.attr.wallpaperTextColorAccent),
Color.WHITE,
mDozeAmount);
mBgView.setVisibility(View.GONE);
}
mLockIcon.setImageTintList(ColorStateList.valueOf(mLockIconColor));
}
void setImageDrawable(Drawable drawable) {
mLockIcon.setImageDrawable(drawable);
if (!mUseBackground) return;
if (drawable == null) {
mBgView.setVisibility(View.INVISIBLE);
} else {
mBgView.setVisibility(View.VISIBLE);
}
}
/**
* Whether or not to render the lock icon background. Mainly used for UDPFS.
*/
public void setUseBackground(boolean useBackground) {
mUseBackground = useBackground;
updateColorAndBackgroundVisibility();
}
/**
* Set the location of the lock icon.
*/
@VisibleForTesting
public void setCenterLocation(@NonNull PointF center, float radius, int drawablePadding) {
mLockIconCenter = center;
mRadius = radius;
mLockIconPadding = drawablePadding;
mLockIcon.setPadding(mLockIconPadding, mLockIconPadding, mLockIconPadding,
mLockIconPadding);
// mSensorProps coordinates assume portrait mode which is OK b/c the keyguard is always in
// portrait.
mSensorRect.set(mLockIconCenter.x - mRadius,
mLockIconCenter.y - mRadius,
mLockIconCenter.x + mRadius,
mLockIconCenter.y + mRadius);
final FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
lp.width = (int) (mSensorRect.right - mSensorRect.left);
lp.height = (int) (mSensorRect.bottom - mSensorRect.top);
lp.topMargin = (int) mSensorRect.top;
lp.setMarginStart((int) mSensorRect.left);
setLayoutParams(lp);
}
@Override
public boolean hasOverlappingRendering() {
return false;
}
float getLocationTop() {
return mLockIconCenter.y - mRadius;
}
/**
* Updates the icon its default state where no visual is shown.
*/
public void clearIcon() {
updateIcon(ICON_NONE, false);
}
/**
* Transition the current icon to a new state
* @param icon type (ie: lock icon, unlock icon, fingerprint icon)
* @param aod whether to use the aod icon variant (some icons don't have aod variants and will
* therefore show no icon)
*/
public void updateIcon(@IconType int icon, boolean aod) {
mIconType = icon;
mAod = aod;
mLockIcon.setImageState(getLockIconState(mIconType, mAod), true);
}
private static int[] getLockIconState(@IconType int icon, boolean aod) {
if (icon == ICON_NONE) {
return new int[0];
}
int[] lockIconState = new int[2];
switch (icon) {
case ICON_LOCK:
lockIconState[0] = android.R.attr.state_first;
break;
case ICON_FINGERPRINT:
lockIconState[0] = android.R.attr.state_middle;
break;
case ICON_UNLOCK:
lockIconState[0] = android.R.attr.state_last;
break;
}
if (aod) {
lockIconState[1] = android.R.attr.state_single;
} else {
lockIconState[1] = -android.R.attr.state_single;
}
return lockIconState;
}
private String typeToString(@IconType int type) {
switch (type) {
case ICON_NONE:
return "none";
case ICON_LOCK:
return "lock";
case ICON_FINGERPRINT:
return "fingerprint";
case ICON_UNLOCK:
return "unlock";
}
return "invalid";
}
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("Lock Icon View Parameters:");
pw.println(" Center in px (x, y)= ("
+ mLockIconCenter.x + ", " + mLockIconCenter.y + ")");
pw.println(" Radius in pixels: " + mRadius);
pw.println(" Drawable padding: " + mLockIconPadding);
pw.println(" mIconType=" + typeToString(mIconType));
pw.println(" mAod=" + mAod);
pw.println("Lock Icon View actual measurements:");
pw.println(" topLeft= (" + getX() + ", " + getY() + ")");
pw.println(" width=" + getWidth() + " height=" + getHeight());
}
}