Update to latest UX margins for clock... and much more

Remove old style clocks and all related code. Begin unraveling code
supporting multiple layouts. Migrate plugin small/big clock support to
the new clock areas.

Fixes: 184073275
Test: atest KeyguardClockSwitchTest KeyguardClockSwitchControllerTest
Change-Id: I38dc2a6df6a710c6da23cbb17fac8d28f3b84764
This commit is contained in:
Matt Pietal
2021-04-07 14:02:22 -04:00
parent d7440a1c68
commit b41253b7da
16 changed files with 135 additions and 843 deletions

View File

@@ -25,55 +25,19 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top">
<FrameLayout
android:id="@+id/clock_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_alignParentTop="true">
<TextClock
android:id="@+id/default_clock_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:paddingBottom="@dimen/title_clock_padding"
android:letterSpacing="0.02"
android:textColor="?attr/wallpaperTextColor"
android:singleLine="true"
style="@style/widget_big"
android:format12Hour="@string/keyguard_widget_12_hours_format"
android:format24Hour="@string/keyguard_widget_24_hours_format"
android:elegantTextHeight="false"
/>
<TextClock
android:id="@+id/default_clock_view_bold"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:gravity="center_horizontal"
android:textColor="?attr/wallpaperTextColor"
android:singleLine="true"
style="@style/widget_title_bold"
android:format12Hour="@string/keyguard_widget_12_hours_format"
android:format24Hour="@string/keyguard_widget_24_hours_format"
android:elegantTextHeight="false"
android:visibility="invisible"
/>
</FrameLayout>
<FrameLayout
android:id="@+id/new_lockscreen_clock_view"
android:id="@+id/lockscreen_clock_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:visibility="gone">
android:paddingStart="@dimen/clock_padding_start">
<com.android.keyguard.AnimatableClockView
android:id="@+id/animatable_clock_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:textSize="86dp"
android:textSize="@dimen/clock_text_size"
android:fontFamily="@font/clock"
android:typeface="monospace"
android:elegantTextHeight="false"
@@ -83,7 +47,7 @@
/>
</FrameLayout>
<FrameLayout
android:id="@+id/new_lockscreen_clock_view_large"
android:id="@+id/lockscreen_clock_view_large"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/keyguard_status_area"
@@ -106,7 +70,8 @@
android:id="@+id/keyguard_status_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/clock_view" />
android:layout_alignParentStart="true"
android:layout_below="@id/lockscreen_clock_view" />
<com.android.systemui.statusbar.phone.NotificationIconContainer
android:id="@+id/left_aligned_notification_icon_container"
@@ -114,6 +79,6 @@
android:layout_height="@dimen/notification_shelf_height"
android:layout_marginTop="@dimen/widget_vertical_padding"
android:layout_below="@id/keyguard_status_area"
android:visibility="gone"
android:paddingStart="@dimen/below_clock_padding_start"
/>
</com.android.keyguard.KeyguardClockSwitch>

View File

@@ -25,6 +25,7 @@
android:layout_gravity="center_horizontal"
android:clipToPadding="false"
android:orientation="vertical"
android:paddingStart="@dimen/below_clock_padding_start"
android:layout_centerHorizontal="true">
<TextView
android:id="@+id/title"

View File

@@ -70,12 +70,5 @@
android:letterSpacing="0.05"
android:ellipsize="marquee"
android:singleLine="true" />
<com.android.systemui.statusbar.phone.NotificationIconContainer
android:id="@+id/clock_notification_icon_container"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_shelf_height"
android:layout_marginTop="@dimen/widget_vertical_padding"
android:visibility="invisible"
/>
</LinearLayout>
</com.android.keyguard.KeyguardStatusView>

View File

@@ -90,4 +90,8 @@
<dimen name="num_pad_key_width">72dp</dimen>
<dimen name="num_pad_row_margin_bottom">6dp</dimen>
<dimen name="num_pad_key_margin_end">12dp</dimen>
<!-- additional offset for clock switch area items -->
<dimen name="clock_padding_start">28dp</dimen>
<dimen name="below_clock_padding_start">32dp</dimen>
</resources>

View File

@@ -1086,8 +1086,9 @@
burn-in on AOD. -->
<dimen name="burn_in_prevention_offset_y_large_clock">42dp</dimen>
<!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) -->
<!-- Clock maximum font size (dp is intentional, to prevent any further scaling) -->
<dimen name="large_clock_text_size">150dp</dimen>
<dimen name="clock_text_size">86dp</dimen>
<!-- The maximum offset in either direction that icons move to prevent burn-in on AOD. -->
<dimen name="default_burn_in_prevention_offset">15dp</dimen>

View File

@@ -4,35 +4,21 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.os.Build;
import android.transition.Fade;
import android.transition.Transition;
import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.transition.TransitionValues;
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.TextClock;
import android.widget.TextView;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.keyguard.dagger.KeyguardStatusViewScope;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.ClockPlugin;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -47,53 +33,21 @@ public class KeyguardClockSwitch extends RelativeLayout {
private static final String TAG = "KeyguardClockSwitch";
/**
* Animation fraction when text is transitioned to/from bold.
*/
private static final float TO_BOLD_TRANSITION_FRACTION = 0.7f;
private static final long CLOCK_OUT_MILLIS = 150;
private static final long CLOCK_IN_MILLIS = 200;
/**
* Layout transition that scales the default clock face.
*/
private final Transition mTransition;
private final ClockVisibilityTransition mClockTransition;
private final ClockVisibilityTransition mBoldClockTransition;
/**
* Optional/alternative clock injected via plugin.
*/
private ClockPlugin mClockPlugin;
/**
* Default clock.
* Frame for small/large clocks
*/
private TextClock mClockView;
/**
* Default clock, bold version.
* Used to transition to bold when shrinking the default clock.
*/
private TextClock mClockViewBold;
/**
* Frame for clock when mode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL.
*/
private FrameLayout mNewLockscreenClockFrame;
private FrameLayout mNewLockscreenLargeClockFrame;
/**
* Frame for default and custom clock.
*/
private FrameLayout mSmallClockFrame;
/**
* Container for big custom clock.
*/
private ViewGroup mBigClockContainer;
private FrameLayout mClockFrame;
private FrameLayout mLargeClockFrame;
private AnimatableClockView mClockView;
private AnimatableClockView mLargeClockView;
/**
* Status area (date and other stuff) shown below the clock. Plugin can decide whether or not to
@@ -117,40 +71,23 @@ public class KeyguardClockSwitch extends RelativeLayout {
/**
* If the Keyguard Slice has a header (big center-aligned text.)
*/
private boolean mShowingHeader;
private boolean mSupportsDarkText;
private int[] mColorPalette;
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
private int mClockSwitchYAmount;
public KeyguardClockSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
mClockTransition = new ClockVisibilityTransition().setCutoff(
1 - TO_BOLD_TRANSITION_FRACTION);
mClockTransition.addTarget(R.id.default_clock_view);
mBoldClockTransition = new ClockVisibilityTransition().setCutoff(
TO_BOLD_TRANSITION_FRACTION);
mBoldClockTransition.addTarget(R.id.default_clock_view_bold);
mTransition = new TransitionSet()
.setOrdering(TransitionSet.ORDERING_TOGETHER)
.addTransition(mClockTransition)
.addTransition(mBoldClockTransition)
.setDuration(KeyguardSliceView.DEFAULT_ANIM_DURATION / 2)
.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
}
/**
* Apply dp changes on font/scale change
*/
public void onDensityOrFontScaleChanged() {
setTextSize(TypedValue.COMPLEX_UNIT_PX, mContext.getResources()
.getDimensionPixelSize(R.dimen.widget_big_font_size));
((TextView) mNewLockscreenLargeClockFrame.getChildAt(0))
.setTextSize(TypedValue.COMPLEX_UNIT_PX, mContext.getResources()
.getDimensionPixelSize(R.dimen.large_clock_text_size));
mLargeClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mContext.getResources()
.getDimensionPixelSize(R.dimen.large_clock_text_size));
mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mContext.getResources()
.getDimensionPixelSize(R.dimen.clock_text_size));
mClockSwitchYAmount = mContext.getResources().getDimensionPixelSize(
R.dimen.keyguard_clock_switch_y_shift);
@@ -163,44 +100,14 @@ public class KeyguardClockSwitch extends RelativeLayout {
return mClockPlugin != null;
}
/**
* Update lock screen mode for testing different layouts
*/
public void updateLockScreenMode(int mode) {
mLockScreenMode = mode;
RelativeLayout.LayoutParams statusAreaLP = (RelativeLayout.LayoutParams)
mKeyguardStatusArea.getLayoutParams();
if (mode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
final int startEndPadding = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
32,
getResources().getDisplayMetrics());
setPaddingRelative(startEndPadding, 0, startEndPadding, 0);
mSmallClockFrame.setVisibility(GONE);
mNewLockscreenClockFrame.setVisibility(VISIBLE);
statusAreaLP.addRule(RelativeLayout.BELOW, R.id.new_lockscreen_clock_view);
statusAreaLP.addRule(RelativeLayout.ALIGN_PARENT_START);
} else {
setPaddingRelative(0, 0, 0, 0);
mSmallClockFrame.setVisibility(VISIBLE);
mNewLockscreenClockFrame.setVisibility(GONE);
statusAreaLP.removeRule(RelativeLayout.ALIGN_PARENT_START);
statusAreaLP.addRule(RelativeLayout.BELOW, R.id.clock_view);
}
requestLayout();
}
@Override
protected void onFinishInflate() {
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);
mNewLockscreenLargeClockFrame = findViewById(R.id.new_lockscreen_clock_view_large);
mSmallClockFrame = findViewById(R.id.clock_view);
mClockFrame = findViewById(R.id.lockscreen_clock_view);
mClockView = findViewById(R.id.animatable_clock_view);
mLargeClockFrame = findViewById(R.id.lockscreen_clock_view_large);
mLargeClockView = findViewById(R.id.animatable_clock_view_large);
mKeyguardStatusArea = findViewById(R.id.keyguard_status_area);
onDensityOrFontScaleChanged();
@@ -210,45 +117,35 @@ public class KeyguardClockSwitch extends RelativeLayout {
// Disconnect from existing plugin.
if (mClockPlugin != null) {
View smallClockView = mClockPlugin.getView();
if (smallClockView != null && smallClockView.getParent() == mSmallClockFrame) {
mSmallClockFrame.removeView(smallClockView);
if (smallClockView != null && smallClockView.getParent() == mClockFrame) {
mClockFrame.removeView(smallClockView);
}
if (mBigClockContainer != null) {
mBigClockContainer.removeAllViews();
updateBigClockVisibility(statusBarState);
View bigClockView = mClockPlugin.getBigClockView();
if (bigClockView != null && bigClockView.getParent() == mLargeClockFrame) {
mLargeClockFrame.removeView(bigClockView);
}
mClockPlugin.onDestroyView();
mClockPlugin = null;
}
if (plugin == null) {
if (mShowingHeader) {
mClockView.setVisibility(View.GONE);
mClockViewBold.setVisibility(View.VISIBLE);
} else {
mClockView.setVisibility(View.VISIBLE);
mClockViewBold.setVisibility(View.INVISIBLE);
}
mKeyguardStatusArea.setVisibility(View.VISIBLE);
mClockView.setVisibility(View.VISIBLE);
mLargeClockView.setVisibility(View.VISIBLE);
return;
}
// Attach small and big clock views to hierarchy.
View smallClockView = plugin.getView();
if (smallClockView != null) {
mSmallClockFrame.addView(smallClockView, -1,
mClockFrame.addView(smallClockView, -1,
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
mClockView.setVisibility(View.GONE);
mClockViewBold.setVisibility(View.GONE);
}
View bigClockView = plugin.getBigClockView();
if (bigClockView != null && mBigClockContainer != null) {
mBigClockContainer.addView(bigClockView);
updateBigClockVisibility(statusBarState);
}
// Hide default clock.
if (!plugin.shouldShowStatusArea()) {
mKeyguardStatusArea.setVisibility(View.GONE);
if (bigClockView != null) {
mLargeClockFrame.addView(bigClockView);
mLargeClockView.setVisibility(View.GONE);
}
// Initialize plugin parameters.
mClockPlugin = plugin;
mClockPlugin.setStyle(getPaint().getStyle());
@@ -259,31 +156,10 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
}
float getClockTextTopPadding() {
Paint.FontMetrics fm = mClockView.getPaint().getFontMetrics();
return fm.ascent - fm.top;
}
/**
* Set container for big clock face appearing behind NSSL and KeyguardStatusView.
*/
public void setBigClockContainer(ViewGroup container, int statusBarState) {
if (mClockPlugin != null && container != null) {
View bigClockView = mClockPlugin.getBigClockView();
if (bigClockView != null) {
container.addView(bigClockView);
}
}
mBigClockContainer = container;
updateBigClockVisibility(statusBarState);
}
/**
* It will also update plugin setStyle if plugin is connected.
*/
public void setStyle(Style style) {
mClockView.getPaint().setStyle(style);
mClockViewBold.getPaint().setStyle(style);
if (mClockPlugin != null) {
mClockPlugin.setStyle(style);
}
@@ -293,48 +169,25 @@ public class KeyguardClockSwitch extends RelativeLayout {
* It will also update plugin setTextColor if plugin is connected.
*/
public void setTextColor(int color) {
mClockView.setTextColor(color);
mClockViewBold.setTextColor(color);
if (mClockPlugin != null) {
mClockPlugin.setTextColor(color);
}
}
public void setShowCurrentUserTime(boolean showCurrentUserTime) {
mClockView.setShowCurrentUserTime(showCurrentUserTime);
mClockViewBold.setShowCurrentUserTime(showCurrentUserTime);
}
public void setTextSize(int unit, float size) {
mClockView.setTextSize(unit, size);
}
public void setFormat12Hour(CharSequence format) {
mClockView.setFormat12Hour(format);
mClockViewBold.setFormat12Hour(format);
}
public void setFormat24Hour(CharSequence format) {
mClockView.setFormat24Hour(format);
mClockViewBold.setFormat24Hour(format);
}
private void animateClockChange(boolean useLargeClock) {
if (mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) return;
if (mClockInAnim != null) mClockInAnim.cancel();
if (mClockOutAnim != null) mClockOutAnim.cancel();
View in, out;
int direction = 1;
if (useLargeClock) {
out = mNewLockscreenClockFrame;
in = mNewLockscreenLargeClockFrame;
out = mClockFrame;
in = mLargeClockFrame;
if (indexOfChild(in) == -1) addView(in);
direction = -1;
} else {
in = mNewLockscreenClockFrame;
out = mNewLockscreenLargeClockFrame;
in = mClockFrame;
out = mLargeClockFrame;
// Must remove in order for notifications to appear in the proper place
removeView(out);
@@ -381,7 +234,6 @@ public class KeyguardClockSwitch extends RelativeLayout {
if (mClockPlugin != null) {
mClockPlugin.setDarkAmount(darkAmount);
}
updateBigClockAlpha();
}
/**
@@ -394,13 +246,6 @@ public class KeyguardClockSwitch extends RelativeLayout {
animateClockChange(!hasVisibleNotifications);
mHasVisibleNotifications = hasVisibleNotifications;
if (mDarkAmount == 0f && mBigClockContainer != null) {
// Starting a fade transition since the visibility of the big clock will change.
TransitionManager.beginDelayedTransition(mBigClockContainer,
new Fade().setDuration(KeyguardSliceView.DEFAULT_ANIM_DURATION / 2).addTarget(
mBigClockContainer));
}
updateBigClockAlpha();
}
public Paint getPaint() {
@@ -433,15 +278,9 @@ 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() {
mClockView.refreshTime();
mClockViewBold.refreshTime();
if (mClockPlugin != null) {
mClockPlugin.onTimeTick();
}
if (Build.IS_DEBUGGABLE) {
// Log for debugging b/130888082 (sysui waking up, but clock not updating)
Log.d(TAG, "Updating clock: " + mClockView.getText());
}
}
/**
@@ -472,240 +311,14 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
}
void updateBigClockVisibility(int statusBarState) {
if (mBigClockContainer == null) {
return;
}
final boolean inDisplayState = statusBarState == StatusBarState.KEYGUARD
|| statusBarState == StatusBarState.SHADE_LOCKED;
final int visibility = !mShowingHeader && inDisplayState
&& mBigClockContainer.getChildCount() != 0 ? View.VISIBLE : View.GONE;
if (mBigClockContainer.getVisibility() != visibility) {
mBigClockContainer.setVisibility(visibility);
}
}
private void updateBigClockAlpha() {
if (mBigClockContainer != null) {
final float alpha = mHasVisibleNotifications ? mDarkAmount : 1f;
mBigClockContainer.setAlpha(alpha);
if (alpha == 0f) {
mBigClockContainer.setVisibility(INVISIBLE);
} else if (mBigClockContainer.getVisibility() == INVISIBLE) {
mBigClockContainer.setVisibility(VISIBLE);
}
}
}
/**
* Sets if the keyguard slice is showing a center-aligned header. We need a smaller clock in
* these cases.
*/
void setKeyguardShowingHeader(boolean hasHeader) {
if (mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL) {
hasHeader = false;
}
if (mShowingHeader == hasHeader) {
return;
}
mShowingHeader = hasHeader;
if (hasCustomClock()) {
return;
}
float smallFontSize = mContext.getResources().getDimensionPixelSize(
R.dimen.widget_small_font_size);
float bigFontSize = mContext.getResources().getDimensionPixelSize(
R.dimen.widget_big_font_size);
mClockTransition.setScale(smallFontSize / bigFontSize);
mBoldClockTransition.setScale(bigFontSize / smallFontSize);
// End any current transitions before starting a new transition so that the new transition
// starts from a good state instead of a potentially bad intermediate state arrived at
// during a transition animation.
TransitionManager.endTransitions((ViewGroup) mClockView.getParent());
if (hasHeader) {
// After the transition, make the default clock GONE so that it doesn't make the
// KeyguardStatusView appear taller in KeyguardClockPositionAlgorithm and elsewhere.
mTransition.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionEnd(Transition transition) {
super.onTransitionEnd(transition);
// Check that header is actually showing. I saw issues where this event was
// fired after the big clock transitioned back to visible, which causes the time
// to completely disappear.
if (mShowingHeader) {
mClockView.setVisibility(View.GONE);
}
transition.removeListener(this);
}
});
}
TransitionManager.beginDelayedTransition((ViewGroup) mClockView.getParent(), mTransition);
mClockView.setVisibility(hasHeader ? View.INVISIBLE : View.VISIBLE);
mClockViewBold.setVisibility(hasHeader ? View.VISIBLE : View.INVISIBLE);
int paddingBottom = mContext.getResources().getDimensionPixelSize(hasHeader
? R.dimen.widget_vertical_padding_clock : R.dimen.title_clock_padding);
mClockView.setPadding(mClockView.getPaddingLeft(), mClockView.getPaddingTop(),
mClockView.getPaddingRight(), paddingBottom);
mClockViewBold.setPadding(mClockViewBold.getPaddingLeft(), mClockViewBold.getPaddingTop(),
mClockViewBold.getPaddingRight(), paddingBottom);
}
/**
* Hide big clock if the keyguard slice is showing a header, need to reduce visual clutter in
* these cases.
*/
public void setKeyguardHidingBigClock(boolean hasHeader) {
if (mBigClockContainer != null) {
mBigClockContainer.setVisibility(hasHeader ? View.GONE : View.VISIBLE);
}
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("KeyguardClockSwitch:");
pw.println(" mClockPlugin: " + mClockPlugin);
pw.println(" mClockView: " + mClockView);
pw.println(" mClockViewBold: " + mClockViewBold);
pw.println(" mSmallClockFrame: " + mSmallClockFrame);
pw.println(" mBigClockContainer: " + mBigClockContainer);
pw.println(" mClockFrame: " + mClockFrame);
pw.println(" mLargeClockFrame: " + mLargeClockFrame);
pw.println(" mKeyguardStatusArea: " + mKeyguardStatusArea);
pw.println(" mDarkAmount: " + mDarkAmount);
pw.println(" mShowingHeader: " + mShowingHeader);
pw.println(" mSupportsDarkText: " + mSupportsDarkText);
pw.println(" mColorPalette: " + Arrays.toString(mColorPalette));
}
/**
* {@link Visibility} transformation that scales the view while it is disappearing/appearing and
* transitions suddenly at a cutoff fraction during the animation.
*/
private class ClockVisibilityTransition extends android.transition.Visibility {
private static final String PROPNAME_VISIBILITY = "systemui:keyguard:visibility";
private float mCutoff;
private float mScale;
/**
* Constructs a transition that switches between visible/invisible at a cutoff and scales in
* size while appearing/disappearing.
*/
ClockVisibilityTransition() {
setCutoff(1f);
setScale(1f);
}
/**
* Sets the transition point between visible/invisible.
*
* @param cutoff The fraction in [0, 1] when the view switches between visible/invisible.
* @return This transition object
*/
public ClockVisibilityTransition setCutoff(float cutoff) {
mCutoff = cutoff;
return this;
}
/**
* Sets the scale factor applied while appearing/disappearing.
*
* @param scale Scale factor applied while appearing/disappearing. When factor is less than
* one, the view will shrink while disappearing. When it is greater than one,
* the view will expand while disappearing.
* @return This transition object
*/
public ClockVisibilityTransition setScale(float scale) {
mScale = scale;
return this;
}
@Override
public void captureStartValues(TransitionValues transitionValues) {
super.captureStartValues(transitionValues);
captureVisibility(transitionValues);
}
@Override
public void captureEndValues(TransitionValues transitionValues) {
super.captureStartValues(transitionValues);
captureVisibility(transitionValues);
}
private void captureVisibility(TransitionValues transitionValues) {
transitionValues.values.put(PROPNAME_VISIBILITY,
transitionValues.view.getVisibility());
}
@Override
public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
TransitionValues endValues) {
if (!sceneRoot.isShown()) {
return null;
}
final float cutoff = mCutoff;
final int startVisibility = View.INVISIBLE;
final int endVisibility = (int) endValues.values.get(PROPNAME_VISIBILITY);
final float startScale = mScale;
final float endScale = 1f;
return createAnimator(view, cutoff, startVisibility, endVisibility, startScale,
endScale);
}
@Override
public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
TransitionValues endValues) {
if (!sceneRoot.isShown()) {
return null;
}
final float cutoff = 1f - mCutoff;
final int startVisibility = View.VISIBLE;
final int endVisibility = (int) endValues.values.get(PROPNAME_VISIBILITY);
final float startScale = 1f;
final float endScale = mScale;
return createAnimator(view, cutoff, startVisibility, endVisibility, startScale,
endScale);
}
private Animator createAnimator(View view, float cutoff, int startVisibility,
int endVisibility, float startScale, float endScale) {
view.setPivotY(view.getHeight() - view.getPaddingBottom());
ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
animator.addUpdateListener(animation -> {
final float fraction = animation.getAnimatedFraction();
if (fraction > cutoff) {
view.setVisibility(endVisibility);
}
final float scale = MathUtils.lerp(startScale, endScale, fraction);
view.setScaleX(scale);
view.setScaleY(scale);
});
animator.addListener(new KeepAwakeAnimationListener(getContext()) {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
view.setVisibility(startVisibility);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
animation.removeListener(this);
}
});
addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionEnd(Transition transition) {
view.setVisibility(endVisibility);
view.setScaleX(1f);
view.setScaleY(1f);
transition.removeListener(this);
}
});
return animator;
}
}
}

View File

@@ -26,11 +26,9 @@ import android.app.smartspace.SmartspaceSession;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
@@ -74,12 +72,12 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
private final BroadcastDispatcher mBroadcastDispatcher;
/**
* Gradient clock for usage when mode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL.
* Clock for both small and large sizes
*/
private AnimatableClockController mNewLockScreenClockViewController;
private FrameLayout mNewLockScreenClockFrame;
private AnimatableClockController mNewLockScreenLargeClockViewController;
private FrameLayout mNewLockScreenLargeClockFrame;
private AnimatableClockController mClockViewController;
private FrameLayout mClockFrame;
private AnimatableClockController mLargeClockViewController;
private FrameLayout mLargeClockFrame;
private PluginManager mPluginManager;
private boolean mIsSmartspaceEnabled;
@@ -88,16 +86,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
private SmartspaceSession mSmartspaceSession;
private SmartspaceSession.Callback mSmartspaceCallback;
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
private final StatusBarStateController.StateListener mStateListener =
new StatusBarStateController.StateListener() {
@Override
public void onStateChanged(int newState) {
mView.updateBigClockVisibility(newState);
}
};
/**
* Listener for changes to the color palette.
*
@@ -114,7 +102,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
};
private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin;
private String mTimeFormat;
// If set, will replace keyguard_status_area
private BcSmartspaceDataPlugin.SmartspaceView mSmartspaceView;
@@ -140,7 +127,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mKeyguardSliceViewController = keyguardSliceViewController;
mNotificationIconAreaController = notificationIconAreaController;
mBroadcastDispatcher = broadcastDispatcher;
mTimeFormat = Settings.System.getString(contentResolver, Settings.System.TIME_12_24);
mPluginManager = pluginManager;
mIsSmartspaceEnabled = featureFlags.isSmartspaceEnabled();
mUiExecutor = uiExecutor;
@@ -159,13 +145,26 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
if (CUSTOM_CLOCKS_ENABLED) {
mClockManager.addOnClockChangedListener(mClockChangedListener);
}
refreshFormat();
mStatusBarStateController.addCallback(mStateListener);
mColorExtractor.addOnColorsChangedListener(mColorsListener);
mView.updateColors(getGradientColors());
updateAodIcons();
mNewLockScreenClockFrame = mView.findViewById(R.id.new_lockscreen_clock_view);
mNewLockScreenLargeClockFrame = mView.findViewById(R.id.new_lockscreen_clock_view_large);
mClockFrame = mView.findViewById(R.id.lockscreen_clock_view);
mLargeClockFrame = mView.findViewById(R.id.lockscreen_clock_view_large);
mClockViewController =
new AnimatableClockController(
mView.findViewById(R.id.animatable_clock_view),
mStatusBarStateController,
mBroadcastDispatcher);
mClockViewController.init();
mLargeClockViewController =
new AnimatableClockController(
mView.findViewById(R.id.animatable_clock_view_large),
mStatusBarStateController,
mBroadcastDispatcher);
mLargeClockViewController.init();
// If a smartspace plugin is detected, replace the existing smartspace
// (keyguard_status_area), and initialize a new session
@@ -181,16 +180,21 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mSmartspaceView = plugin.getView(mView);
mSmartspaceView.registerDataProvider(plugin);
View asView = (View) mSmartspaceView;
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
MATCH_PARENT, WRAP_CONTENT);
lp.addRule(RelativeLayout.BELOW, R.id.new_lockscreen_clock_view);
mView.addView((View) mSmartspaceView, ksaIndex, lp);
lp.addRule(RelativeLayout.BELOW, R.id.lockscreen_clock_view);
mView.addView(asView, ksaIndex, lp);
int padding = getContext().getResources()
.getDimensionPixelSize(R.dimen.below_clock_padding_start);
asView.setPadding(padding, 0, padding, 0);
View nic = mView.findViewById(
com.android.systemui.R.id.left_aligned_notification_icon_container);
lp = (RelativeLayout.LayoutParams) nic.getLayoutParams();
lp.addRule(RelativeLayout.BELOW, ((View) mSmartspaceView).getId());
lp.addRule(RelativeLayout.BELOW, asView.getId());
nic.setLayoutParams(lp);
createSmartspaceSession(plugin);
@@ -230,7 +234,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
if (CUSTOM_CLOCKS_ENABLED) {
mClockManager.removeOnClockChangedListener(mClockChangedListener);
}
mStatusBarStateController.removeCallback(mStateListener);
mColorExtractor.removeOnColorsChangedListener(mColorsListener);
mView.setClockPlugin(null, mStatusBarStateController.getState());
@@ -249,13 +252,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mView.onDensityOrFontScaleChanged();
}
/**
* Set container for big clock face appearing behind NSSL and KeyguardStatusView.
*/
public void setBigClockContainer(ViewGroup bigClockContainer) {
mView.setBigClockContainer(bigClockContainer, mStatusBarStateController.getState());
}
/**
* Set whether or not the lock screen is showing notifications.
*/
@@ -291,9 +287,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
* Refresh clock. Called in response to TIME_TICK broadcasts.
*/
void refresh() {
if (mNewLockScreenClockViewController != null) {
mNewLockScreenClockViewController.refreshTime();
mNewLockScreenLargeClockViewController.refreshTime();
if (mClockViewController != null) {
mClockViewController.refreshTime();
mLargeClockViewController.refreshTime();
}
mView.refresh();
@@ -307,86 +303,45 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
*/
void updatePosition(int x, float scale, AnimationProperties props, boolean animate) {
x = getCurrentLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? -x : x;
if (mNewLockScreenClockFrame != null) {
PropertyAnimator.setProperty(mNewLockScreenClockFrame, AnimatableProperty.TRANSLATION_X,
x, props, animate);
PropertyAnimator.setProperty(mNewLockScreenLargeClockFrame, AnimatableProperty.SCALE_X,
scale, props, animate);
PropertyAnimator.setProperty(mNewLockScreenLargeClockFrame, AnimatableProperty.SCALE_Y,
scale, props, animate);
}
PropertyAnimator.setProperty(mClockFrame, AnimatableProperty.TRANSLATION_X,
x, props, animate);
PropertyAnimator.setProperty(mLargeClockFrame, AnimatableProperty.SCALE_X,
scale, props, animate);
PropertyAnimator.setProperty(mLargeClockFrame, AnimatableProperty.SCALE_Y,
scale, props, animate);
if (mSmartspaceView != null) {
PropertyAnimator.setProperty((View) mSmartspaceView, AnimatableProperty.TRANSLATION_X,
x, props, animate);
}
mKeyguardSliceViewController.updatePosition(x, props, animate);
mNotificationIconAreaController.updatePosition(x, props, animate);
}
/**
* Update lockscreen mode that may change clock display.
*/
void updateLockScreenMode(int mode) {
mLockScreenMode = mode;
if (mode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
if (mNewLockScreenClockViewController == null) {
mNewLockScreenClockViewController =
new AnimatableClockController(
mView.findViewById(R.id.animatable_clock_view),
mStatusBarStateController,
mBroadcastDispatcher);
mNewLockScreenClockViewController.init();
mNewLockScreenLargeClockViewController =
new AnimatableClockController(
mView.findViewById(R.id.animatable_clock_view_large),
mStatusBarStateController,
mBroadcastDispatcher);
mNewLockScreenLargeClockViewController.init();
}
} else {
mNewLockScreenClockViewController = null;
mNewLockScreenLargeClockViewController = null;
}
mView.updateLockScreenMode(mLockScreenMode);
updateAodIcons();
}
void updateTimeZone(TimeZone timeZone) {
mView.onTimeZoneChanged(timeZone);
if (mNewLockScreenClockViewController != null) {
mNewLockScreenClockViewController.onTimeZoneChanged(timeZone);
mNewLockScreenLargeClockViewController.onTimeZoneChanged(timeZone);
if (mClockViewController != null) {
mClockViewController.onTimeZoneChanged(timeZone);
mLargeClockViewController.onTimeZoneChanged(timeZone);
}
}
void refreshFormat(String timeFormat) {
mTimeFormat = timeFormat;
Patterns.update(mResources);
mView.setFormat12Hour(Patterns.sClockView12);
mView.setFormat24Hour(Patterns.sClockView24);
mView.onTimeFormatChanged(mTimeFormat);
if (mNewLockScreenClockViewController != null) {
mNewLockScreenClockViewController.refreshFormat();
mNewLockScreenLargeClockViewController.refreshFormat();
if (mClockViewController != null) {
mClockViewController.refreshFormat();
mLargeClockViewController.refreshFormat();
}
}
void refreshFormat() {
refreshFormat(mTimeFormat);
}
private void updateAodIcons() {
NotificationIconContainer nic = (NotificationIconContainer)
mView.findViewById(
com.android.systemui.R.id.left_aligned_notification_icon_container);
if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
// alt icon area is set in KeyguardClockSwitchController
mNotificationIconAreaController.setupAodIcons(nic, mLockScreenMode);
} else {
nic.setVisibility(View.GONE);
}
// alt icon area is set in KeyguardClockSwitchController
mNotificationIconAreaController.setupAodIcons(nic);
}
private void setClockPlugin(ClockPlugin plugin) {

View File

@@ -44,7 +44,6 @@ import java.io.PrintWriter;
* - keyguard clock
* - logout button (on certain managed devices)
* - owner information (if set)
* - notification icons (shown on AOD)
*/
public class KeyguardStatusView extends GridLayout {
private static final boolean DEBUG = KeyguardConstants.DEBUG;
@@ -59,7 +58,6 @@ public class KeyguardStatusView extends GridLayout {
private TextView mOwnerInfo;
private boolean mCanShowOwnerInfo = true; // by default, try to show the owner information here
private KeyguardSliceView mKeyguardSlice;
private View mNotificationIcons;
private Runnable mPendingMarqueeStart;
private Handler mHandler;
@@ -132,13 +130,11 @@ public class KeyguardStatusView extends GridLayout {
protected void onFinishInflate() {
super.onFinishInflate();
mLogoutView = findViewById(R.id.logout);
mNotificationIcons = findViewById(R.id.clock_notification_icon_container);
if (mLogoutView != null) {
mLogoutView.setOnClickListener(this::onLogoutClicked);
}
mClockView = findViewById(R.id.keyguard_clock_container);
mClockView.setShowCurrentUserTime(true);
if (KeyguardClockAccessibilityDelegate.isNeeded(mContext)) {
mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
}
@@ -161,22 +157,10 @@ public class KeyguardStatusView extends GridLayout {
*/
private void onSliceContentChanged() {
final boolean hasHeader = mKeyguardSlice.hasHeader();
mClockView.setKeyguardShowingHeader(hasHeader);
if (mShowingHeader == hasHeader) {
return;
}
mShowingHeader = hasHeader;
if (mNotificationIcons != null) {
// Update top margin since header has appeared/disappeared.
MarginLayoutParams params = (MarginLayoutParams) mNotificationIcons.getLayoutParams();
params.setMargins(params.leftMargin,
hasHeader ? mIconTopMarginWithHeader : mIconTopMargin,
params.rightMargin,
params.bottomMargin);
mNotificationIcons.setLayoutParams(params);
}
mClockView.setKeyguardHidingBigClock(hasHeader);
}
@Override
@@ -293,13 +277,6 @@ public class KeyguardStatusView extends GridLayout {
int expanded = mOwnerInfo.getBottom() + mOwnerInfo.getPaddingBottom();
int toRemove = (int) ((expanded - collapsed) * ratio);
setBottom(getMeasuredHeight() - toRemove);
if (mNotificationIcons != null) {
// We're using scrolling in order not to overload the translation which is used
// when appearing the icons
mNotificationIcons.setScrollY(toRemove);
}
} else if (mNotificationIcons != null){
mNotificationIcons.setScrollY(0);
}
}

View File

@@ -18,15 +18,12 @@ package com.android.keyguard;
import android.os.UserHandle;
import android.util.Slog;
import android.view.View;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.NotificationIconContainer;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ViewController;
@@ -49,7 +46,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
private final KeyguardClockSwitchController mKeyguardClockSwitchController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final ConfigurationController mConfigurationController;
private final NotificationIconAreaController mNotificationIconAreaController;
private final DozeParameters mDozeParameters;
private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
@@ -63,14 +59,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
KeyguardStateController keyguardStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
ConfigurationController configurationController,
NotificationIconAreaController notificationIconAreaController,
DozeParameters dozeParameters) {
super(keyguardStatusView);
mKeyguardSliceViewController = keyguardSliceViewController;
mKeyguardClockSwitchController = keyguardClockSwitchController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mConfigurationController = configurationController;
mNotificationIconAreaController = notificationIconAreaController;
mDozeParameters = dozeParameters;
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
dozeParameters);
@@ -87,7 +81,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
protected void onViewAttached() {
mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
mConfigurationController.addCallback(mConfigurationListener);
updateAodIcons();
}
@Override
@@ -237,17 +230,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mKeyguardClockSwitchController.refresh();
}
private void updateAodIcons() {
NotificationIconContainer nic = (NotificationIconContainer)
mView.findViewById(com.android.systemui.R.id.clock_notification_icon_container);
if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL) {
// alternate icon area is set in KeyguardClockSwitchController
mNotificationIconAreaController.setupAodIcons(nic, mLockScreenMode);
} else {
nic.setVisibility(View.GONE);
}
}
private boolean shouldShowLogout() {
return mKeyguardUpdateMonitor.isLogoutEnabled()
&& KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
@@ -271,16 +253,9 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
@Override
public void onLockScreenModeChanged(int mode) {
mLockScreenMode = mode;
mKeyguardClockSwitchController.updateLockScreenMode(mode);
mKeyguardSliceViewController.updateLockScreenMode(mode);
if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
mView.setCanShowOwnerInfo(false);
mView.updateLogoutView(false);
} else {
mView.setCanShowOwnerInfo(true);
mView.updateLogoutView(false);
}
updateAodIcons();
mView.setCanShowOwnerInfo(false);
mView.updateLogoutView(false);
}
@Override
@@ -293,11 +268,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mKeyguardClockSwitchController.updateTimeZone(timeZone);
}
@Override
public void onTimeFormatChanged(String timeFormat) {
mKeyguardClockSwitchController.refreshFormat(timeFormat);
}
@Override
public void onKeyguardVisibilityChanged(boolean showing) {
if (showing) {
@@ -320,7 +290,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
@Override
public void onUserSwitchComplete(int userId) {
mKeyguardClockSwitchController.refreshFormat();
mView.updateOwnerInfo();
mView.updateLogoutView(shouldShowLogout());
}

View File

@@ -161,15 +161,14 @@ public class NotificationIconAreaController implements
/**
* Called by the Keyguard*ViewController whose view contains the aod icons.
*/
public void setupAodIcons(@NonNull NotificationIconContainer aodIcons,
int lockScreenMode) {
public void setupAodIcons(@NonNull NotificationIconContainer aodIcons) {
boolean changed = mAodIcons != null;
if (changed) {
mAodIcons.setAnimationsEnabled(false);
mAodIcons.removeAllViews();
}
mAodIcons = aodIcons;
mAodIcons.setOnLockScreen(true, lockScreenMode);
mAodIcons.setOnLockScreen(true);
updateAodIconsVisibility(false /* animate */);
updateAnimations();
if (changed) {

View File

@@ -35,7 +35,6 @@ import android.view.animation.Interpolator;
import androidx.collection.ArrayMap;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
@@ -151,7 +150,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
private float mActualPaddingStart = NO_VALUE;
private boolean mDozing;
private boolean mOnLockScreen;
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
private boolean mInNotificationIconShelf;
private boolean mChangingViewPositions;
private int mAddAnimationStartIndex = -1;
@@ -464,33 +462,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
mFirstVisibleIconState = mIconStates.get(getChildAt(0));
}
boolean center = mOnLockScreen
&& mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
if (center && translationX < getLayoutEnd()) {
float initialTranslation =
mFirstVisibleIconState == null ? 0 : mFirstVisibleIconState.xTranslation;
float contentWidth = 0;
if (mLastVisibleIconState != null) {
contentWidth = mLastVisibleIconState.xTranslation + mIconSize;
contentWidth = Math.min(getWidth(), contentWidth) - initialTranslation;
}
float availableSpace = getLayoutEnd() - getActualPaddingStart();
float delta = (availableSpace - contentWidth) / 2;
if (firstOverflowIndex != -1) {
// If we have an overflow, only count those half for centering because the dots
// don't have a lot of visual weight.
float deltaIgnoringOverflow = (getLayoutEnd() - mVisualOverflowStart) / 2;
delta = (deltaIgnoringOverflow + delta) / 2;
}
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
IconState iconState = mIconStates.get(view);
iconState.xTranslation += delta;
}
}
if (isLayoutRtl()) {
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
@@ -698,9 +669,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
* Set whether the device is on the lockscreen and which lockscreen mode the device is
* configured to. Depending on these values, the layout of the AOD icons change.
*/
public void setOnLockScreen(boolean onLockScreen, int lockScreenMode) {
public void setOnLockScreen(boolean onLockScreen) {
mOnLockScreen = onLockScreen;
mLockScreenMode = lockScreenMode;
}
public void setInNotificationIconShelf(boolean inShelf) {

View File

@@ -76,7 +76,6 @@ import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardClockSwitchController;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardStatusViewController;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -798,11 +797,6 @@ public class NotificationPanelViewController extends PanelViewController {
statusBarViewComponent.getKeyguardStatusBarViewController();
mKeyguarStatusBarViewController.init();
// Re-associate the clock container with the keyguard clock switch.
KeyguardClockSwitchController keyguardClockSwitchController =
statusViewComponent.getKeyguardClockSwitchController();
keyguardClockSwitchController.setBigClockContainer(mBigClockContainer);
if (mKeyguardUserSwitcherController != null) {
// Try to close the switcher so that callbacks are triggered if necessary.
// Otherwise, NPV can get into a state where some of the views are still hidden

View File

@@ -31,8 +31,6 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import com.android.internal.colorextraction.ColorExtractor;
@@ -94,6 +92,10 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
private FeatureFlags mFeatureFlags;
@Mock
private Executor mExecutor;
@Mock
private AnimatableClockView mClockView;
@Mock
private AnimatableClockView mLargeClockView;
private KeyguardClockSwitchController mController;
@@ -101,9 +103,15 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
public void setup() {
MockitoAnnotations.initMocks(this);
when(mView.findViewById(com.android.systemui.R.id.left_aligned_notification_icon_container))
when(mView.findViewById(R.id.left_aligned_notification_icon_container))
.thenReturn(mNotificationIcons);
when(mView.getContext()).thenReturn(getContext());
when(mView.findViewById(R.id.animatable_clock_view)).thenReturn(mClockView);
when(mView.findViewById(R.id.animatable_clock_view_large)).thenReturn(mLargeClockView);
when(mClockView.getContext()).thenReturn(getContext());
when(mLargeClockView.getContext()).thenReturn(getContext());
when(mFeatureFlags.isSmartspaceEnabled()).thenReturn(true);
when(mView.isAttachedToWindow()).thenReturn(true);
when(mResources.getString(anyInt())).thenReturn("h:mm");
@@ -165,32 +173,10 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
listenerArgumentCaptor.getValue().onViewDetachedFromWindow(mView);
verify(mStatusBarStateController).removeCallback(
any(StatusBarStateController.StateListener.class));
verify(mColorExtractor).removeOnColorsChangedListener(
any(ColorExtractor.OnColorsChangedListener.class));
}
@Test
public void testBigClockPassesStatusBarState() {
ViewGroup testView = new FrameLayout(mContext);
mController.init();
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
mController.setBigClockContainer(testView);
verify(mView).setBigClockContainer(testView, StatusBarState.SHADE);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
mController.setBigClockContainer(testView);
verify(mView).setBigClockContainer(testView, StatusBarState.KEYGUARD);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED);
mController.setBigClockContainer(testView);
verify(mView).setBigClockContainer(testView, StatusBarState.SHADE_LOCKED);
}
@Test
public void testPluginPassesStatusBarState() {
ArgumentCaptor<ClockManager.ClockChangedListener> listenerArgumentCaptor =
@@ -245,8 +231,6 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
private void verifyAttachment(VerificationMode times) {
verify(mClockManager, times).addOnClockChangedListener(
any(ClockManager.ClockChangedListener.class));
verify(mStatusBarStateController, times).addCallback(
any(StatusBarStateController.StateListener.class));
verify(mColorExtractor, times).addOnColorsChangedListener(
any(ColorExtractor.OnColorsChangedListener.class));
verify(mView, times).updateColors(mGradientColors);

View File

@@ -21,9 +21,7 @@ import static android.view.View.VISIBLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -33,7 +31,6 @@ import android.graphics.Paint.Style;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -48,8 +45,6 @@ import com.android.systemui.statusbar.StatusBarState;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@@ -59,14 +54,13 @@ import org.mockito.MockitoAnnotations;
// the keyguard_clcok_switch layout is inflated.
@RunWithLooper(setAsMainLooper = true)
public class KeyguardClockSwitchTest extends SysuiTestCase {
private FrameLayout mClockContainer;
private FrameLayout mBigClockContainer;
private FrameLayout mClockFrame;
private FrameLayout mLargeClockFrame;
private TextClock mBigClock;
@Mock
TextClock mClockView;
private AnimatableClockView mClockView;
private AnimatableClockView mLargeClockView;
View mMockKeyguardSliceView;
@InjectMocks
KeyguardClockSwitch mKeyguardClockSwitch;
@Before
@@ -95,11 +89,12 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
});
mKeyguardClockSwitch =
(KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null);
mClockContainer = mKeyguardClockSwitch.findViewById(R.id.clock_view);
mBigClockContainer = new FrameLayout(getContext());
mClockFrame = mKeyguardClockSwitch.findViewById(R.id.lockscreen_clock_view);
mClockView = mKeyguardClockSwitch.findViewById(R.id.animatable_clock_view);
mLargeClockFrame = mKeyguardClockSwitch.findViewById(R.id.lockscreen_clock_view_large);
mLargeClockView = mKeyguardClockSwitch.findViewById(R.id.animatable_clock_view_large);
mBigClock = new TextClock(getContext());
MockitoAnnotations.initMocks(this);
when(mClockView.getPaint()).thenReturn(mock(TextPaint.class));
}
@Test
@@ -110,33 +105,28 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
verify(mClockView).setVisibility(GONE);
assertThat(plugin.getView().getParent()).isEqualTo(mClockContainer);
assertThat(mClockView.getVisibility()).isEqualTo(GONE);
assertThat(plugin.getView().getParent()).isEqualTo(mClockFrame);
}
@Test
public void onPluginConnected_showPluginBigClock() {
// GIVEN that the container for the big clock has visibility GONE
mBigClockContainer.setVisibility(GONE);
mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// AND the plugin returns a view for the big clock
// GIVEN the plugin returns a view for the big clock
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
// AND in the keyguard state
mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the plugin is connected
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// THEN the big clock container is visible and it is the parent of the
// big clock view.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mBigClock.getParent()).isEqualTo(mBigClockContainer);
assertThat(mLargeClockView.getVisibility()).isEqualTo(View.GONE);
assertThat(mBigClock.getParent()).isEqualTo(mLargeClockFrame);
}
@Test
public void onPluginConnected_nullView() {
ClockPlugin plugin = mock(ClockPlugin.class);
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
verify(mClockView, never()).setVisibility(GONE);
assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
}
@Test
@@ -150,7 +140,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
when(plugin2.getView()).thenReturn(new TextClock(getContext()));
mKeyguardClockSwitch.setClockPlugin(plugin2, StatusBarState.KEYGUARD);
// THEN only the view from the second plugin should be a child of KeyguardClockSwitch.
assertThat(plugin2.getView().getParent()).isEqualTo(mClockContainer);
assertThat(plugin2.getView().getParent()).isEqualTo(mClockFrame);
assertThat(plugin1.getView().getParent()).isNull();
}
@@ -170,33 +160,28 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
ClockPlugin plugin = mock(ClockPlugin.class);
TextClock pluginView = new TextClock(getContext());
when(plugin.getView()).thenReturn(pluginView);
mClockView.setVisibility(GONE);
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
assertThat(mClockView.getVisibility()).isEqualTo(GONE);
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
verify(mClockView).setVisibility(VISIBLE);
assertThat(plugin.getView().getParent()).isNull();
}
@Test
public void onPluginDisconnected_hidePluginBigClock() {
// GIVEN that the big clock container is visible
FrameLayout bigClockContainer = new FrameLayout(getContext());
bigClockContainer.setVisibility(VISIBLE);
mKeyguardClockSwitch.setBigClockContainer(bigClockContainer, StatusBarState.KEYGUARD);
// AND the plugin returns a view for the big clock
// GIVEN the plugin returns a view for the big clock
ClockPlugin plugin = mock(ClockPlugin.class);
TextClock pluginView = new TextClock(getContext());
when(plugin.getBigClockView()).thenReturn(pluginView);
// AND in the keyguard state
mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the plugin is connected and then disconnected
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
// THEN the big lock container is GONE and the big clock view doesn't have
// a parent.
assertThat(bigClockContainer.getVisibility()).isEqualTo(GONE);
assertThat(mLargeClockView.getVisibility()).isEqualTo(VISIBLE);
assertThat(pluginView.getParent()).isNull();
}
@@ -205,7 +190,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
ClockPlugin plugin = mock(ClockPlugin.class);
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
verify(mClockView, never()).setVisibility(GONE);
assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
}
@Test
@@ -220,7 +205,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
// WHEN the second plugin is disconnected
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
// THEN the default clock should be shown.
verify(mClockView).setVisibility(VISIBLE);
assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
assertThat(plugin1.getView().getParent()).isNull();
assertThat(plugin2.getView().getParent()).isNull();
}
@@ -237,13 +222,6 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
verify(clockPlugin).onDestroyView();
}
@Test
public void setTextColor_defaultClockSetTextColor() {
mKeyguardClockSwitch.setTextColor(Color.YELLOW);
verify(mClockView).setTextColor(Color.YELLOW);
}
@Test
public void setTextColor_pluginClockSetTextColor() {
ClockPlugin plugin = mock(ClockPlugin.class);
@@ -256,16 +234,6 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
verify(plugin).setTextColor(Color.WHITE);
}
@Test
public void setStyle_defaultClockSetStyle() {
TextPaint paint = mock(TextPaint.class);
Style style = mock(Style.class);
doReturn(paint).when(mClockView).getPaint();
mKeyguardClockSwitch.setStyle(style);
verify(paint).setStyle(style);
}
@Test
public void setStyle_pluginClockSetStyle() {
@@ -279,98 +247,4 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
verify(plugin).setStyle(style);
}
@Test
public void onStateChanged_GoneInShade() {
// GIVEN that the big clock container is visible
mBigClockContainer.setVisibility(View.VISIBLE);
mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// WHEN transitioned to SHADE state
mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.SHADE);
// THEN the container is gone.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void onStateChanged_VisibleInKeyguard() {
// GIVEN that the big clock container is gone
mBigClockContainer.setVisibility(View.GONE);
mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// AND GIVEN that a plugin is active.
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// WHEN transitioned to KEYGUARD state
mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// THEN the container is visible.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void setBigClockContainer_visible() {
// GIVEN that the big clock container is visible
mBigClockContainer.setVisibility(View.VISIBLE);
// AND GIVEN that a plugin is active.
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// AND in the keyguard state
mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the container is associated with the clock switch
mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// THEN the container remains visible.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void setBigClockContainer_gone() {
// GIVEN that the big clock container is gone
mBigClockContainer.setVisibility(View.GONE);
// AND GIVEN that a plugin is active.
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// AND in the keyguard state
mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the container is associated with the clock switch
mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// THEN the container is made visible.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void setKeyguardHidingBigClock_gone() {
// GIVEN that the container for the big clock has visibility GONE
mBigClockContainer.setVisibility(GONE);
mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// AND the plugin returns a view for the big clock
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
// AND in the keyguard state
mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the plugin is connected
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// WHEN the container set hiding clock as true
mKeyguardClockSwitch.setKeyguardHidingBigClock(true);
// THEN the container is gone.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void setKeyguardHidingBigClock_visible() {
// GIVEN that the container for the big clock has visibility GONE
mBigClockContainer.setVisibility(GONE);
mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// AND the plugin returns a view for the big clock
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
// AND in the keyguard state
mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the plugin is connected
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// WHEN the container set hiding clock as false
mKeyguardClockSwitch.setKeyguardHidingBigClock(false);
// THEN the container is made visible.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
}
}

View File

@@ -23,7 +23,6 @@ import android.testing.AndroidTestingRunner;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -50,8 +49,6 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
@Mock
ConfigurationController mConfigurationController;
@Mock
NotificationIconAreaController mNotificationIconAreaController;
@Mock
DozeParameters mDozeParameters;
private KeyguardStatusViewController mController;
@@ -67,7 +64,6 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
mKeyguardStateController,
mKeyguardUpdateMonitor,
mConfigurationController,
mNotificationIconAreaController,
mDozeParameters);
}

View File

@@ -25,7 +25,6 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.plugins.DarkIconDispatcher;
@@ -107,9 +106,7 @@ public class NotificationIconAreaControllerTest extends SysuiTestCase {
@Test
public void testAppearResetsTranslation() {
mController.setupAodIcons(
mAodIcons,
KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL);
mController.setupAodIcons(mAodIcons);
when(mDozeParameters.shouldControlScreenOff()).thenReturn(false);
mController.appearAodIcons();
verify(mAodIcons).setTranslationY(0);