1 /* 2 * Copyright (C) 2019 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.clock; 17 18 import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; 19 20 import android.content.Context; 21 import android.content.res.Resources; 22 import android.util.AttributeSet; 23 import android.util.MathUtils; 24 import android.view.View; 25 import android.widget.FrameLayout; 26 27 import com.android.systemui.R; 28 29 /** 30 * Positions clock faces (analog, digital, typographic) and handles pixel shifting 31 * to prevent screen burn-in. 32 */ 33 public class ClockLayout extends FrameLayout { 34 35 private static final int ANALOG_CLOCK_SHIFT_FACTOR = 3; 36 /** 37 * Clock face views. 38 */ 39 private View mAnalogClock; 40 41 /** 42 * Pixel shifting amplitudes used to prevent screen burn-in. 43 */ 44 private int mBurnInPreventionOffsetX; 45 private int mBurnInPreventionOffsetY; 46 47 private float mDarkAmount; 48 ClockLayout(Context context)49 public ClockLayout(Context context) { 50 this(context, null); 51 } 52 ClockLayout(Context context, AttributeSet attrs)53 public ClockLayout(Context context, AttributeSet attrs) { 54 this(context, attrs, 0); 55 } 56 ClockLayout(Context context, AttributeSet attrs, int defStyleAttr)57 public ClockLayout(Context context, AttributeSet attrs, int defStyleAttr) { 58 super(context, attrs, defStyleAttr); 59 } 60 61 @Override onFinishInflate()62 protected void onFinishInflate() { 63 super.onFinishInflate(); 64 mAnalogClock = findViewById(R.id.analog_clock); 65 66 // Get pixel shifting X, Y amplitudes from resources. 67 Resources resources = getResources(); 68 mBurnInPreventionOffsetX = resources.getDimensionPixelSize( 69 R.dimen.burn_in_prevention_offset_x); 70 mBurnInPreventionOffsetY = resources.getDimensionPixelSize( 71 R.dimen.burn_in_prevention_offset_y); 72 } 73 74 @Override onLayout(boolean changed, int left, int top, int right, int bottom)75 protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 76 super.onLayout(changed, left, top, right, bottom); 77 positionChildren(); 78 } 79 onTimeChanged()80 void onTimeChanged() { 81 positionChildren(); 82 } 83 84 /** 85 * See {@link com.android.systemui.plugins.ClockPlugin#setDarkAmount(float)}. 86 */ setDarkAmount(float darkAmount)87 void setDarkAmount(float darkAmount) { 88 mDarkAmount = darkAmount; 89 positionChildren(); 90 } 91 positionChildren()92 private void positionChildren() { 93 final float offsetX = MathUtils.lerp(0f, 94 getBurnInOffset(mBurnInPreventionOffsetX * 2, true) - mBurnInPreventionOffsetX, 95 mDarkAmount); 96 final float offsetY = MathUtils.lerp(0f, 97 getBurnInOffset(mBurnInPreventionOffsetY * 2, false) 98 - 0.5f * mBurnInPreventionOffsetY, 99 mDarkAmount); 100 101 // Put the analog clock in the middle of the screen. 102 if (mAnalogClock != null) { 103 mAnalogClock.setX(Math.max(0f, 0.5f * (getWidth() - mAnalogClock.getWidth())) 104 + ANALOG_CLOCK_SHIFT_FACTOR * offsetX); 105 mAnalogClock.setY(Math.max(0f, 0.5f * (getHeight() - mAnalogClock.getHeight())) 106 + ANALOG_CLOCK_SHIFT_FACTOR * offsetY); 107 } 108 } 109 } 110