Merge "Add gradient clock to AOD/LS behind LS flag"
This commit is contained in:
committed by
Android (Google) Code Review
commit
f1f0bd6951
@@ -61,6 +61,28 @@
|
||||
android:visibility="invisible"
|
||||
/>
|
||||
</FrameLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/new_lockscreen_clock_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:visibility="gone">
|
||||
<com.android.keyguard.GradientTextClock
|
||||
android:id="@+id/gradient_clock_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="100dp"
|
||||
android:letterSpacing="0.02"
|
||||
android:lineSpacingMultiplier=".8"
|
||||
android:includeFontPadding="false"
|
||||
android:fontFamily="sans-serif"
|
||||
android:typeface="monospace"
|
||||
android:format12Hour="hh\nmm"
|
||||
android:format24Hour="HH\nmm"
|
||||
android:elegantTextHeight="false"
|
||||
/>
|
||||
</FrameLayout>
|
||||
<include layout="@layout/keyguard_status_area"
|
||||
android:id="@+id/keyguard_status_area"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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.graphics.LinearGradient;
|
||||
import android.graphics.Shader;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.TextClock;
|
||||
|
||||
/**
|
||||
* Displays the time with the hour positioned above the minutes. (ie: 09 above 30 is 9:30)
|
||||
* The time's text color is a gradient that changes its colors based on its controller.
|
||||
*/
|
||||
public class GradientTextClock extends TextClock {
|
||||
private int[] mGradientColors;
|
||||
private float[] mPositions;
|
||||
|
||||
public GradientTextClock(Context context) {
|
||||
this(context, null, 0, 0);
|
||||
}
|
||||
|
||||
public GradientTextClock(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0, 0);
|
||||
}
|
||||
|
||||
public GradientTextClock(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public GradientTextClock(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
addOnLayoutChangeListener(mOnLayoutChangeListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
removeOnLayoutChangeListener(mOnLayoutChangeListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshTime() {
|
||||
updatePaint();
|
||||
super.refreshTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFormat12Hour(CharSequence format) {
|
||||
super.setFormat12Hour(FORMAT_12);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFormat24Hour(CharSequence format) {
|
||||
super.setFormat24Hour(FORMAT_24);
|
||||
}
|
||||
|
||||
public void setGradientColors(int[] colors) {
|
||||
mGradientColors = colors;
|
||||
}
|
||||
|
||||
public void setColorPositions(float[] positions) {
|
||||
mPositions = positions;
|
||||
}
|
||||
|
||||
private void updatePaint() {
|
||||
getPaint().setShader(
|
||||
new LinearGradient(
|
||||
getX(), getY(), getX(), getMeasuredHeight() + getY(),
|
||||
mGradientColors, mPositions, Shader.TileMode.REPEAT));
|
||||
}
|
||||
|
||||
private final OnLayoutChangeListener mOnLayoutChangeListener =
|
||||
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
|
||||
if (bottom != oldBottom || top != oldTop) {
|
||||
updatePaint();
|
||||
}
|
||||
};
|
||||
|
||||
public static final CharSequence FORMAT_12 = "hh\nmm";
|
||||
public static final CharSequence FORMAT_24 = "HH\nmm";
|
||||
}
|
||||
@@ -71,6 +71,16 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
*/
|
||||
private TextClock mClockViewBold;
|
||||
|
||||
/**
|
||||
* Gradient clock for usage when mode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL.
|
||||
*/
|
||||
private TimeBasedColorsClockController mNewLockscreenClockViewController;
|
||||
|
||||
/**
|
||||
* Frame for clock when mode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL.
|
||||
*/
|
||||
private FrameLayout mNewLockscreenClockFrame;
|
||||
|
||||
/**
|
||||
* Frame for default and custom clock.
|
||||
*/
|
||||
@@ -137,23 +147,22 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
mLockScreenMode = mode;
|
||||
RelativeLayout.LayoutParams statusAreaLP = (RelativeLayout.LayoutParams)
|
||||
mKeyguardStatusArea.getLayoutParams();
|
||||
RelativeLayout.LayoutParams clockLP = (RelativeLayout.LayoutParams)
|
||||
mSmallClockFrame.getLayoutParams();
|
||||
|
||||
if (mode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
|
||||
statusAreaLP.removeRule(RelativeLayout.BELOW);
|
||||
statusAreaLP.addRule(RelativeLayout.LEFT_OF, R.id.clock_view);
|
||||
statusAreaLP.addRule(RelativeLayout.ALIGN_PARENT_START);
|
||||
mSmallClockFrame.setVisibility(GONE);
|
||||
mNewLockscreenClockFrame.setVisibility(VISIBLE);
|
||||
mNewLockscreenClockViewController.init();
|
||||
|
||||
clockLP.addRule(RelativeLayout.ALIGN_PARENT_END);
|
||||
clockLP.width = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
statusAreaLP.removeRule(RelativeLayout.BELOW);
|
||||
statusAreaLP.addRule(RelativeLayout.LEFT_OF, R.id.new_lockscreen_clock_view);
|
||||
statusAreaLP.addRule(RelativeLayout.ALIGN_PARENT_START);
|
||||
} else {
|
||||
mSmallClockFrame.setVisibility(VISIBLE);
|
||||
mNewLockscreenClockFrame.setVisibility(GONE);
|
||||
|
||||
statusAreaLP.removeRule(RelativeLayout.LEFT_OF);
|
||||
statusAreaLP.removeRule(RelativeLayout.ALIGN_PARENT_START);
|
||||
statusAreaLP.addRule(RelativeLayout.BELOW, R.id.clock_view);
|
||||
|
||||
clockLP.removeRule(RelativeLayout.ALIGN_PARENT_END);
|
||||
clockLP.width = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
}
|
||||
|
||||
requestLayout();
|
||||
@@ -164,6 +173,9 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
super.onFinishInflate();
|
||||
mClockView = findViewById(R.id.default_clock_view);
|
||||
mClockViewBold = findViewById(R.id.default_clock_view_bold);
|
||||
mNewLockscreenClockFrame = findViewById(R.id.new_lockscreen_clock_view);
|
||||
mNewLockscreenClockViewController =
|
||||
new TimeBasedColorsClockController(findViewById(R.id.gradient_clock_view));
|
||||
mSmallClockFrame = findViewById(R.id.clock_view);
|
||||
mKeyguardStatusArea = findViewById(R.id.keyguard_status_area);
|
||||
}
|
||||
@@ -336,6 +348,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
* Refresh the time of the clock, due to either time tick broadcast or doze time tick alarm.
|
||||
*/
|
||||
public void refresh() {
|
||||
mNewLockscreenClockViewController.refreshTime(System.currentTimeMillis());
|
||||
mClockView.refreshTime();
|
||||
mClockViewBold.refreshTime();
|
||||
if (mClockPlugin != null) {
|
||||
|
||||
@@ -33,9 +33,11 @@ import android.text.TextUtils;
|
||||
import android.text.TextUtils.TruncateAt;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.slice.SliceItem;
|
||||
@@ -55,8 +57,10 @@ import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* View visible under the clock on the lock screen and AoD.
|
||||
@@ -86,6 +90,8 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
private float mRowWithHeaderTextSize;
|
||||
private View.OnClickListener mOnClickListener;
|
||||
|
||||
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
|
||||
|
||||
public KeyguardSliceView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
@@ -142,6 +148,40 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the lockscreen mode which may change the layout of the keyguard slice view.
|
||||
*/
|
||||
public void updateLockScreenMode(int mode) {
|
||||
mLockScreenMode = mode;
|
||||
if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
|
||||
// add top padding to better align with top of clock
|
||||
final int topPadding = (int) TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
20,
|
||||
getResources().getDisplayMetrics());
|
||||
mTitle.setPaddingRelative(0, topPadding, 0, 0);
|
||||
mTitle.setGravity(Gravity.START);
|
||||
setGravity(Gravity.START);
|
||||
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
lp.removeRule(RelativeLayout.CENTER_HORIZONTAL);
|
||||
setLayoutParams(lp);
|
||||
} else {
|
||||
final int horizontalPaddingDpValue = (int) TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
44,
|
||||
getResources().getDisplayMetrics()
|
||||
);
|
||||
mTitle.setPaddingRelative(horizontalPaddingDpValue, 0, horizontalPaddingDpValue, 0);
|
||||
mTitle.setGravity(Gravity.CENTER_HORIZONTAL);
|
||||
setGravity(Gravity.CENTER_HORIZONTAL);
|
||||
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
|
||||
setLayoutParams(lp);
|
||||
}
|
||||
mRow.setLockscreenMode(mode);
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
Map<View, PendingIntent> showSlice(RowContent header, List<SliceContent> subItems) {
|
||||
Trace.beginSection("KeyguardSliceView#showSlice");
|
||||
mHasHeader = header != null;
|
||||
@@ -166,6 +206,8 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
final int startIndex = mHasHeader ? 1 : 0; // First item is header; skip it
|
||||
mRow.setVisibility(subItemsCount > 0 ? VISIBLE : GONE);
|
||||
LinearLayout.LayoutParams layoutParams = (LayoutParams) mRow.getLayoutParams();
|
||||
layoutParams.gravity = mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL
|
||||
? Gravity.START : Gravity.CENTER;
|
||||
layoutParams.topMargin = mHasHeader ? mRowWithHeaderPadding : mRowPadding;
|
||||
mRow.setLayoutParams(layoutParams);
|
||||
|
||||
@@ -282,6 +324,7 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
pw.println(" mTextColor: " + Integer.toHexString(mTextColor));
|
||||
pw.println(" mDarkAmount: " + mDarkAmount);
|
||||
pw.println(" mHasHeader: " + mHasHeader);
|
||||
pw.println(" mLockScreenMode: " + mLockScreenMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -291,6 +334,8 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
}
|
||||
|
||||
public static class Row extends LinearLayout {
|
||||
private Set<KeyguardSliceTextView> mKeyguardSliceTextViewSet = new HashSet();
|
||||
private int mLockScreenModeRow = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
|
||||
|
||||
/**
|
||||
* This view is visible in AOD, which means that the device will sleep if we
|
||||
@@ -361,12 +406,18 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int childCount = getChildCount();
|
||||
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = getChildAt(i);
|
||||
if (child instanceof KeyguardSliceTextView) {
|
||||
((KeyguardSliceTextView) child).setMaxWidth(width / 3);
|
||||
if (mLockScreenModeRow == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
|
||||
((KeyguardSliceTextView) child).setMaxWidth(Integer.MAX_VALUE);
|
||||
} else {
|
||||
((KeyguardSliceTextView) child).setMaxWidth(width / 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
@@ -384,6 +435,42 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View view, int index) {
|
||||
super.addView(view, index);
|
||||
|
||||
if (view instanceof KeyguardSliceTextView) {
|
||||
((KeyguardSliceTextView) view).setLockScreenMode(mLockScreenModeRow);
|
||||
mKeyguardSliceTextViewSet.add((KeyguardSliceTextView) view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeView(View view) {
|
||||
super.removeView(view);
|
||||
if (view instanceof KeyguardSliceTextView) {
|
||||
mKeyguardSliceTextViewSet.remove((KeyguardSliceTextView) view);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the lockscreen mode which may change the layout of this view.
|
||||
*/
|
||||
public void setLockscreenMode(int mode) {
|
||||
mLockScreenModeRow = mode;
|
||||
if (mLockScreenModeRow == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
|
||||
setOrientation(LinearLayout.VERTICAL);
|
||||
setGravity(Gravity.START);
|
||||
} else {
|
||||
setOrientation(LinearLayout.HORIZONTAL);
|
||||
setGravity(Gravity.CENTER);
|
||||
}
|
||||
|
||||
for (KeyguardSliceTextView textView : mKeyguardSliceTextViewSet) {
|
||||
textView.setLockScreenMode(mLockScreenModeRow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -392,6 +479,7 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
@VisibleForTesting
|
||||
static class KeyguardSliceTextView extends TextView implements
|
||||
ConfigurationController.ConfigurationListener {
|
||||
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
|
||||
|
||||
@StyleRes
|
||||
private static int sStyleId = R.style.TextAppearance_Keyguard_Secondary;
|
||||
@@ -432,9 +520,16 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
|
||||
private void updatePadding() {
|
||||
boolean hasText = !TextUtils.isEmpty(getText());
|
||||
int horizontalPadding = (int) getContext().getResources()
|
||||
int padding = (int) getContext().getResources()
|
||||
.getDimension(R.dimen.widget_horizontal_padding) / 2;
|
||||
setPadding(horizontalPadding, 0, horizontalPadding * (hasText ? 1 : -1), 0);
|
||||
if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
|
||||
// orientation is vertical, so add padding to top & bottom
|
||||
setPadding(0, padding, 0, padding * (hasText ? 1 : -1));
|
||||
} else {
|
||||
// oreintation is horizontal, so add padding to left & right
|
||||
setPadding(padding, 0, padding * (hasText ? 1 : -1), 0);
|
||||
}
|
||||
|
||||
setCompoundDrawablePadding((int) mContext.getResources()
|
||||
.getDimension(R.dimen.widget_icon_padding));
|
||||
}
|
||||
@@ -461,5 +556,18 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the lockscreen mode which may change the layout of this view.
|
||||
*/
|
||||
public void setLockScreenMode(int mode) {
|
||||
mLockScreenMode = mode;
|
||||
if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
|
||||
setGravity(Gravity.START);
|
||||
} else {
|
||||
setGravity(Gravity.CENTER);
|
||||
}
|
||||
updatePadding();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import com.android.systemui.keyguard.KeyguardSliceProvider;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.util.ViewController;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -55,10 +56,10 @@ import javax.inject.Inject;
|
||||
|
||||
/** Controller for a {@link KeyguardSliceView}. */
|
||||
@KeyguardStatusViewScope
|
||||
public class KeyguardSliceViewController implements Dumpable {
|
||||
public class KeyguardSliceViewController extends ViewController<KeyguardSliceView> implements
|
||||
Dumpable {
|
||||
private static final String TAG = "KeyguardSliceViewCtrl";
|
||||
|
||||
private final KeyguardSliceView mView;
|
||||
private final ActivityStarter mActivityStarter;
|
||||
private final ConfigurationController mConfigurationController;
|
||||
private final TunerService mTunerService;
|
||||
@@ -68,41 +69,7 @@ public class KeyguardSliceViewController implements Dumpable {
|
||||
private Uri mKeyguardSliceUri;
|
||||
private Slice mSlice;
|
||||
private Map<View, PendingIntent> mClickActions;
|
||||
|
||||
private final View.OnAttachStateChangeListener mOnAttachStateChangeListener =
|
||||
new View.OnAttachStateChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onViewAttachedToWindow(View v) {
|
||||
|
||||
Display display = mView.getDisplay();
|
||||
if (display != null) {
|
||||
mDisplayId = display.getDisplayId();
|
||||
}
|
||||
mTunerService.addTunable(mTunable, Settings.Secure.KEYGUARD_SLICE_URI);
|
||||
// Make sure we always have the most current slice
|
||||
if (mDisplayId == DEFAULT_DISPLAY && mLiveData != null) {
|
||||
mLiveData.observeForever(mObserver);
|
||||
}
|
||||
mConfigurationController.addCallback(mConfigurationListener);
|
||||
mDumpManager.registerDumpable(
|
||||
TAG + "@" + Integer.toHexString(
|
||||
KeyguardSliceViewController.this.hashCode()),
|
||||
KeyguardSliceViewController.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(View v) {
|
||||
|
||||
// TODO(b/117344873) Remove below work around after this issue be fixed.
|
||||
if (mDisplayId == DEFAULT_DISPLAY) {
|
||||
mLiveData.removeObserver(mObserver);
|
||||
}
|
||||
mTunerService.removeTunable(mTunable);
|
||||
mConfigurationController.removeCallback(mConfigurationListener);
|
||||
mDumpManager.unregisterDumpable(TAG);
|
||||
}
|
||||
};
|
||||
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
|
||||
|
||||
TunerService.Tunable mTunable = (key, newValue) -> setupUri(newValue);
|
||||
|
||||
@@ -133,24 +100,57 @@ public class KeyguardSliceViewController implements Dumpable {
|
||||
};
|
||||
|
||||
@Inject
|
||||
public KeyguardSliceViewController(KeyguardSliceView keyguardSliceView,
|
||||
public KeyguardSliceViewController(
|
||||
KeyguardSliceView keyguardSliceView,
|
||||
ActivityStarter activityStarter,
|
||||
ConfigurationController configurationController, TunerService tunerService,
|
||||
ConfigurationController configurationController,
|
||||
TunerService tunerService,
|
||||
DumpManager dumpManager) {
|
||||
mView = keyguardSliceView;
|
||||
super(keyguardSliceView);
|
||||
mActivityStarter = activityStarter;
|
||||
mConfigurationController = configurationController;
|
||||
mTunerService = tunerService;
|
||||
mDumpManager = dumpManager;
|
||||
}
|
||||
|
||||
/** Initialize the controller. */
|
||||
public void init() {
|
||||
if (mView.isAttachedToWindow()) {
|
||||
mOnAttachStateChangeListener.onViewAttachedToWindow(mView);
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
Display display = mView.getDisplay();
|
||||
if (display != null) {
|
||||
mDisplayId = display.getDisplayId();
|
||||
}
|
||||
mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
|
||||
mView.setOnClickListener(mOnClickListener);
|
||||
mTunerService.addTunable(mTunable, Settings.Secure.KEYGUARD_SLICE_URI);
|
||||
// Make sure we always have the most current slice
|
||||
if (mDisplayId == DEFAULT_DISPLAY && mLiveData != null) {
|
||||
mLiveData.observeForever(mObserver);
|
||||
}
|
||||
mConfigurationController.addCallback(mConfigurationListener);
|
||||
mDumpManager.registerDumpable(
|
||||
TAG + "@" + Integer.toHexString(
|
||||
KeyguardSliceViewController.this.hashCode()),
|
||||
KeyguardSliceViewController.this);
|
||||
mView.updateLockScreenMode(mLockScreenMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewDetached() {
|
||||
// TODO(b/117344873) Remove below work around after this issue be fixed.
|
||||
if (mDisplayId == DEFAULT_DISPLAY) {
|
||||
mLiveData.removeObserver(mObserver);
|
||||
}
|
||||
mTunerService.removeTunable(mTunable);
|
||||
mConfigurationController.removeCallback(mConfigurationListener);
|
||||
mDumpManager.unregisterDumpable(
|
||||
TAG + "@" + Integer.toHexString(
|
||||
KeyguardSliceViewController.this.hashCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the lockscreen mode which may change the layout of the keyguard slice view.
|
||||
*/
|
||||
public void updateLockScreenMode(int mode) {
|
||||
mLockScreenMode = mode;
|
||||
mView.updateLockScreenMode(mLockScreenMode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -224,10 +224,10 @@ public class KeyguardSliceViewController implements Dumpable {
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
|
||||
pw.println(" mSlice: " + mSlice);
|
||||
pw.println(" mClickActions: " + mClickActions);
|
||||
pw.println(" mLockScreenMode: " + mLockScreenMode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,6 +267,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
||||
@Override
|
||||
public void onLockScreenModeChanged(int mode) {
|
||||
mKeyguardClockSwitchController.updateLockScreenMode(mode);
|
||||
mKeyguardSliceViewController.updateLockScreenMode(mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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 com.android.systemui.util.ViewController;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
/**
|
||||
* Changes the color of the text clock based on the time of day.
|
||||
*/
|
||||
public class TimeBasedColorsClockController extends ViewController<GradientTextClock> {
|
||||
private final int[] mGradientColors = new int[3];
|
||||
private final float[] mPositions = new float[3];
|
||||
|
||||
public TimeBasedColorsClockController(GradientTextClock view) {
|
||||
super(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
refreshTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewDetached() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the time for this view. Also updates any color changes.
|
||||
*/
|
||||
public void refreshTime(long timeInMillis) {
|
||||
Calendar now = new GregorianCalendar();
|
||||
now.setTimeInMillis(timeInMillis);
|
||||
updateColors(now);
|
||||
updatePositions(now);
|
||||
mView.refreshTime();
|
||||
}
|
||||
|
||||
private int getTimeIndex(Calendar now) {
|
||||
int hour = now.get(Calendar.HOUR_OF_DAY); // 0 - 23
|
||||
if (hour < mTimes[0]) {
|
||||
return mTimes.length - 1;
|
||||
}
|
||||
|
||||
for (int i = 1; i < mTimes.length; i++) {
|
||||
if (hour < mTimes[i]) {
|
||||
return i - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return mTimes.length - 1;
|
||||
}
|
||||
|
||||
private void updateColors(Calendar now) {
|
||||
final int index = getTimeIndex(now);
|
||||
for (int i = 0; i < mGradientColors.length; i++) {
|
||||
mGradientColors[i] = COLORS[index][i];
|
||||
}
|
||||
mView.setGradientColors(mGradientColors);
|
||||
}
|
||||
|
||||
private void updatePositions(Calendar now) {
|
||||
final int index = getTimeIndex(now);
|
||||
|
||||
final Calendar startTime = new GregorianCalendar();
|
||||
startTime.setTimeInMillis(now.getTimeInMillis());
|
||||
startTime.set(Calendar.HOUR_OF_DAY, mTimes[index]);
|
||||
if (startTime.getTimeInMillis() > now.getTimeInMillis()) {
|
||||
// start should be earlier than 'now'
|
||||
startTime.add(Calendar.DATE, -1);
|
||||
}
|
||||
|
||||
final Calendar endTime = new GregorianCalendar();
|
||||
endTime.setTimeInMillis(now.getTimeInMillis());
|
||||
if (index == mTimes.length - 1) {
|
||||
endTime.set(Calendar.HOUR_OF_DAY, mTimes[0]);
|
||||
endTime.add(Calendar.DATE, 1); // end time is tomorrow
|
||||
} else {
|
||||
endTime.set(Calendar.HOUR_OF_DAY, mTimes[index + 1]);
|
||||
}
|
||||
|
||||
long totalTimeInThisColorGradient = endTime.getTimeInMillis() - startTime.getTimeInMillis();
|
||||
long timeIntoThisColorGradient = now.getTimeInMillis() - startTime.getTimeInMillis();
|
||||
float percentageWithinGradient =
|
||||
(float) timeIntoThisColorGradient / (float) totalTimeInThisColorGradient;
|
||||
|
||||
for (int i = 0; i < mPositions.length; i++) {
|
||||
// currently hard-coded .3 movement of gradient
|
||||
mPositions[i] = POSITIONS[index][i] - (.3f * percentageWithinGradient);
|
||||
}
|
||||
mView.setColorPositions(mPositions);
|
||||
}
|
||||
|
||||
private static final int[] SUNRISE = new int[] {0xFF6F75AA, 0xFFAFF0FF, 0xFFFFDEBF};
|
||||
private static final int[] DAY = new int[] {0xFF9BD8FB, 0xFFD7F5FF, 0xFFFFF278};
|
||||
private static final int[] NIGHT = new int[] {0xFF333D5E, 0xFFC5A1D6, 0xFF907359};
|
||||
|
||||
private static final float[] SUNRISE_START_POSITIONS = new float[] {.3f, .5f, .8f};
|
||||
private static final float[] DAY_START_POSITIONS = new float[] {.4f, .8f, 1f};
|
||||
private static final float[] NIGHT_START_POSITIONS = new float[] {.25f, .5f, .8f};
|
||||
|
||||
// TODO (b/170228350): use TwilightManager to set sunrise/sunset times
|
||||
private final int mSunriseTime = 6; // 6am
|
||||
private final int mDaytime = 9; // 9 am
|
||||
private final int mNightTime = 19; // 7pm
|
||||
|
||||
private int[] mTimes = new int[] {
|
||||
mSunriseTime,
|
||||
mDaytime,
|
||||
mNightTime
|
||||
};
|
||||
private static final int[][] COLORS = new int[][] {
|
||||
SUNRISE,
|
||||
DAY,
|
||||
NIGHT
|
||||
};
|
||||
private static final float[][] POSITIONS = new float[][] {
|
||||
SUNRISE_START_POSITIONS,
|
||||
DAY_START_POSITIONS,
|
||||
NIGHT_START_POSITIONS
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user