Add custom bubble clock face.

Bug: 122301289
Test: Using adb to set the settings value switches to bubble clock.
Change-Id: I9b5ab62796204cfdce7b9beb147f34f80b0db167
This commit is contained in:
Robert Snoeberger
2019-01-10 18:29:38 -05:00
parent 7c1bbb7135
commit 046ee9ceca
12 changed files with 732 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="200dp"
android:width="200dp"
android:viewportHeight="100"
android:viewportWidth="100">
<path
android:fillColor="#000000"
android:pathData="M50.082,14.199m-13.985,0a13.985,13.985 0,1 1,27.97 0a13.985,13.985 0,1 1,-27.97 0"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="200dp"
android:width="200dp"
android:viewportHeight="100"
android:viewportWidth="100" >
<path
android:fillColor="#000000"
android:pathData="M50.082,0.025L50.082,0.025A13.985,15.63 0,0 1,64.067 15.656L64.067,49.029A13.985,15.63 0,0 1,50.082 64.659L50.082,64.659A13.985,15.63 0,0 1,36.097 49.029L36.097,15.656A13.985,15.63 0,0 1,50.082 0.025z"/>
</vector>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2019 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.
-->
<com.android.keyguard.clock.ClockLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextClock
android:id="@+id/digital_clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:letterSpacing="0.03"
android:singleLine="true"
style="@style/widget_big"
android:format12Hour="@string/keyguard_widget_12_hours_format"
android:format24Hour="@string/keyguard_widget_24_hours_format"
/>
<com.android.keyguard.clock.ImageClock
android:id="@+id/analog_clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/minute_hand"
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@drawable/bubble_minute_hand"
android:tint="@color/bubbleMinuteHandColor"
/>
<ImageView
android:id="@+id/hour_hand"
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@drawable/bubble_hour_hand"
android:tint="@color/bubbleHourHandColor"
/>
</com.android.keyguard.clock.ImageClock>
</com.android.keyguard.clock.ClockLayout>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2019 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.
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_alignParentTop="true">
<TextClock
android:id="@+id/lock_screen_clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:letterSpacing="0.03"
android:singleLine="true"
style="@style/widget_big"
android:format12Hour="@string/keyguard_widget_12_hours_format"
android:format24Hour="@string/keyguard_widget_24_hours_format" />
/>
</FrameLayout>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2019 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.
-->
<resources>
<!-- Default color for hour hand of Bubble clock. -->
<color name="bubbleHourHandColor">#C97343</color>
<!-- Default color for minute hand of Bubble clock. -->
<color name="bubbleMinuteHandColor">#F5C983</color>
</resources>

View File

@@ -1,9 +1,15 @@
package com.android.keyguard;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -12,6 +18,7 @@ import android.widget.TextClock;
import androidx.annotation.VisibleForTesting;
import com.android.keyguard.clock.BubbleClockController;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.ClockPlugin;
import com.android.systemui.statusbar.StatusBarState;
@@ -19,13 +26,19 @@ import com.android.systemui.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.ExtensionController.Extension;
import java.util.Objects;
import java.util.TimeZone;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
*/
public class KeyguardClockSwitch extends RelativeLayout {
private LayoutInflater mLayoutInflater;
private final ContentResolver mContentResolver;
/**
* Optional/alternative clock injected via plugin.
*/
@@ -79,12 +92,25 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
};
private final ContentObserver mContentObserver =
new ContentObserver(new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
if (mClockExtension != null) {
mClockExtension.reload();
}
}
};
public KeyguardClockSwitch(Context context) {
this(context, null);
}
public KeyguardClockSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
mLayoutInflater = LayoutInflater.from(context);
mContentResolver = context.getContentResolver();
}
@Override
@@ -101,7 +127,22 @@ public class KeyguardClockSwitch extends RelativeLayout {
mClockExtension = Dependency.get(ExtensionController.class).newExtension(ClockPlugin.class)
.withPlugin(ClockPlugin.class)
.withCallback(mClockPluginConsumer)
// Using withDefault even though this isn't the default as a workaround.
// ExtensionBulider doesn't provide the ability to supply a ClockPlugin
// instance based off of the value of a setting. Since multiple "default"
// can be provided, using a supplier that changes the settings value.
// A null return will cause Extension#reload to look at the next "default"
// supplier.
.withDefault(
new SettingsGattedSupplier(
mContentResolver,
Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
BubbleClockController.class.getName(),
() -> BubbleClockController.build(mLayoutInflater)))
.build();
mContentResolver.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE),
false, mContentObserver);
Dependency.get(StatusBarStateController.class).addCallback(mStateListener);
}
@@ -109,6 +150,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mClockExtension.destroy();
mContentResolver.unregisterContentObserver(mContentObserver);
Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
}
@@ -262,4 +304,44 @@ public class KeyguardClockSwitch extends RelativeLayout {
StatusBarStateController.StateListener getStateListener() {
return mStateListener;
}
/**
* Supplier that only gets an instance when a settings value matches expected value.
*/
private static class SettingsGattedSupplier implements Supplier<ClockPlugin> {
private final ContentResolver mContentResolver;
private final String mKey;
private final String mValue;
private final Supplier<ClockPlugin> mSupplier;
/**
* Constructs a supplier that changes secure setting key against value.
*
* @param contentResolver Used to look up settings value.
* @param key Settings key.
* @param value If the setting matches this values that get supplies a ClockPlugin
* instance.
* @param supplier Supplier of ClockPlugin instance, only used if the setting
* matches value.
*/
SettingsGattedSupplier(ContentResolver contentResolver, String key, String value,
Supplier<ClockPlugin> supplier) {
mContentResolver = contentResolver;
mKey = key;
mValue = value;
mSupplier = supplier;
}
/**
* Returns null if the settings value doesn't match the expected value.
*
* A null return causes Extension#reload to skip this supplier and move to the next.
*/
@Override
public ClockPlugin get() {
final String currentValue = Settings.Secure.getString(mContentResolver, mKey);
return Objects.equals(currentValue, mValue) ? mSupplier.get() : null;
}
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 2019 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.clock;
import android.graphics.Paint.Style;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextClock;
import com.android.keyguard.R;
import com.android.systemui.plugins.ClockPlugin;
import java.util.TimeZone;
/**
* Controller for Bubble clock that can appear on lock screen and AOD.
*/
public class BubbleClockController implements ClockPlugin {
/**
* Custom clock shown on AOD screen and behind stack scroller on lock.
*/
private View mView;
private TextClock mDigitalClock;
private ImageClock mAnalogClock;
/**
* Small clock shown on lock screen above stack scroller.
*/
private View mLockClockContainer;
private TextClock mLockClock;
/**
* Controller for transition to dark state.
*/
private CrossFadeDarkController mDarkController;
private BubbleClockController() { }
/**
* Create a BubbleClockController instance.
*
* @param layoutInflater Inflater used to inflate custom clock views.
*/
public static BubbleClockController build(LayoutInflater layoutInflater) {
BubbleClockController controller = new BubbleClockController();
controller.createViews(layoutInflater);
return controller;
}
private void createViews(LayoutInflater layoutInflater) {
mView = layoutInflater.inflate(R.layout.bubble_clock, null);
mDigitalClock = (TextClock) mView.findViewById(R.id.digital_clock);
mAnalogClock = (ImageClock) mView.findViewById(R.id.analog_clock);
mLockClockContainer = layoutInflater.inflate(R.layout.digital_clock, null);
mLockClock = (TextClock) mLockClockContainer.findViewById(R.id.lock_screen_clock);
mLockClock.setVisibility(View.GONE);
mDarkController = new CrossFadeDarkController(mDigitalClock, mLockClock);
}
@Override
public View getView() {
return mLockClockContainer;
}
@Override
public View getBigClockView() {
return mView;
}
@Override
public void setStyle(Style style) {}
@Override
public void setTextColor(int color) {
mLockClock.setTextColor(color);
mDigitalClock.setTextColor(color);
}
@Override
public void dozeTimeTick() {
mAnalogClock.onTimeChanged();
}
@Override
public void setDarkAmount(float darkAmount) {
mDarkController.setDarkAmount(darkAmount);
}
@Override
public void onTimeZoneChanged(TimeZone timeZone) {
mAnalogClock.onTimeZoneChanged(timeZone);
}
@Override
public boolean shouldShowStatusArea() {
return false;
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (C) 2019 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.clock;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import com.android.keyguard.R;
/**
* Positions clock faces (analog, digital, typographic) and handles pixel shifting
* to prevent screen burn-in.
*/
public class ClockLayout extends FrameLayout {
/**
* Clock face views.
*/
private View mDigitalClock;
private View mAnalogClock;
/**
* Pixel shifting amplitidues used to prevent screen burn-in.
*/
private int mBurnInPreventionOffsetX;
private int mBurnInPreventionOffsetY;
public ClockLayout(Context context) {
this(context, null);
}
public ClockLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ClockLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mDigitalClock = findViewById(R.id.digital_clock);
mAnalogClock = findViewById(R.id.analog_clock);
// Get pixel shifting X, Y amplitudes from resources.
Resources resources = getResources();
mBurnInPreventionOffsetX = resources.getDimensionPixelSize(
R.dimen.burn_in_prevention_offset_x);
mBurnInPreventionOffsetY = resources.getDimensionPixelSize(
R.dimen.burn_in_prevention_offset_y);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
final float offsetX = getBurnInOffset(mBurnInPreventionOffsetX, true);
final float offsetY = getBurnInOffset(mBurnInPreventionOffsetY, false);
// Put digital clock in two left corner of the screen.
if (mDigitalClock != null) {
mDigitalClock.setX(0.1f * getWidth() + offsetX);
mDigitalClock.setY(0.1f * getHeight() + offsetY);
}
// Put the analog clock in the middle of the screen.
if (mAnalogClock != null) {
mAnalogClock.setX(Math.max(0f, 0.5f * (getWidth() - mAnalogClock.getWidth()))
+ offsetX);
mAnalogClock.setY(Math.max(0f, 0.5f * (getHeight() - mAnalogClock.getHeight()))
+ offsetY);
}
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2019 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.clock;
import android.view.View;
/**
* Controls transition to dark state by cross fading between views.
*/
final class CrossFadeDarkController {
private final View mFadeInView;
private final View mFadeOutView;
/**
* Creates a new controller that fades between views.
*
* @param fadeInView View to fade in when transitioning to AOD.
* @param fadeOutView View to fade out when transitioning to AOD.
*/
CrossFadeDarkController(View fadeInView, View fadeOutView) {
mFadeInView = fadeInView;
mFadeOutView = fadeOutView;
}
/**
* Sets the amount the system has transitioned to the dark state.
*
* @param darkAmount Amount of transition to dark state: 1f for AOD and 0f for lock screen.
*/
void setDarkAmount(float darkAmount) {
mFadeInView.setAlpha(Math.max(0f, 2f * darkAmount - 1f));
if (darkAmount == 0f) {
mFadeInView.setVisibility(View.GONE);
} else {
if (mFadeInView.getVisibility() == View.GONE) {
mFadeInView.setVisibility(View.VISIBLE);
}
}
mFadeOutView.setAlpha(Math.max(0f, 1f - 2f * darkAmount));
if (darkAmount == 1f) {
mFadeOutView.setVisibility(View.GONE);
} else {
if (mFadeOutView.getVisibility() == View.GONE) {
mFadeOutView.setVisibility(View.VISIBLE);
}
}
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2019 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.clock;
import android.content.Context;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.android.keyguard.R;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
/**
* Clock composed of two images that rotate with the time.
*
* The images are the clock hands. ImageClock expects two child ImageViews
* with ids hour_hand and minute_hand.
*/
public class ImageClock extends FrameLayout {
private ImageView mHourHand;
private ImageView mMinuteHand;
private Calendar mTime;
private String mDescFormat;
private TimeZone mTimeZone;
public ImageClock(Context context) {
this(context, null);
}
public ImageClock(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ImageClock(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mTime = Calendar.getInstance();
mDescFormat = ((SimpleDateFormat) DateFormat.getTimeFormat(context)).toLocalizedPattern();
}
/**
* Call when the time changes to update the rotation of the clock hands.
*/
public void onTimeChanged() {
mTime.setTimeInMillis(System.currentTimeMillis());
final float hourAngle = mTime.get(Calendar.HOUR) * 30f;
mHourHand.setRotation(hourAngle);
final float minuteAngle = mTime.get(Calendar.MINUTE) * 6f;
mMinuteHand.setRotation(minuteAngle);
setContentDescription(DateFormat.format(mDescFormat, mTime));
invalidate();
}
/**
* Call when the time zone has changed to update clock hands.
*
* @param timeZone The updated time zone that will be used.
*/
public void onTimeZoneChanged(TimeZone timeZone) {
mTimeZone = timeZone;
mTime.setTimeZone(timeZone);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mHourHand = findViewById(R.id.hour_hand);
mMinuteHand = findViewById(R.id.minute_hand);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mTime = Calendar.getInstance(mTimeZone != null ? mTimeZone : TimeZone.getDefault());
onTimeChanged();
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2019 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.clock;
import static com.google.common.truth.Truth.assertThat;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.android.systemui.SysuiTestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
public final class BubbleClockControllerTest extends SysuiTestCase {
private BubbleClockController mClockController;
@Before
public void setUp() {
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
mClockController = BubbleClockController.build(layoutInflater);
}
@Test
public void setDarkAmount_fadeIn() {
ViewGroup smallClockFrame = (ViewGroup) mClockController.getView();
View smallClock = smallClockFrame.getChildAt(0);
// WHEN dark amount is set to AOD
mClockController.setDarkAmount(1f);
// THEN small clock should not be shown.
assertThat(smallClock.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void setTextColor_setDigitalClock() {
ViewGroup smallClock = (ViewGroup) mClockController.getView();
// WHEN text color is set
mClockController.setTextColor(42);
// THEN child of small clock should have text color set.
TextView digitalClock = (TextView) smallClock.getChildAt(0);
assertThat(digitalClock.getCurrentTextColor()).isEqualTo(42);
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2019 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.clock;
import static com.google.common.truth.Truth.assertThat;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.view.View;
import android.widget.TextView;
import com.android.systemui.SysuiTestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
public final class CrossFadeDarkControllerTest extends SysuiTestCase {
private View mViewFadeIn;
private View mViewFadeOut;
private CrossFadeDarkController mDarkController;
@Before
public void setUp() {
mViewFadeIn = new TextView(getContext());
mViewFadeIn.setVisibility(View.VISIBLE);
mViewFadeIn.setAlpha(1f);
mViewFadeOut = new TextView(getContext());
mViewFadeOut.setVisibility(View.VISIBLE);
mViewFadeOut.setAlpha(1f);
mDarkController = new CrossFadeDarkController(mViewFadeIn, mViewFadeOut);
}
@Test
public void setDarkAmount_fadeIn() {
// WHEN dark amount corresponds to AOD
mDarkController.setDarkAmount(1f);
// THEN fade in view should be faded in and fade out view faded out.
assertThat(mViewFadeIn.getAlpha()).isEqualTo(1f);
assertThat(mViewFadeIn.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mViewFadeOut.getAlpha()).isEqualTo(0f);
assertThat(mViewFadeOut.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void setDarkAmount_fadeOut() {
// WHEN dark amount corresponds to lock screen
mDarkController.setDarkAmount(0f);
// THEN fade out view should bed faded out and fade in view faded in.
assertThat(mViewFadeIn.getAlpha()).isEqualTo(0f);
assertThat(mViewFadeIn.getVisibility()).isEqualTo(View.GONE);
assertThat(mViewFadeOut.getAlpha()).isEqualTo(1f);
assertThat(mViewFadeOut.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void setDarkAmount_partialFadeIn() {
// WHEN dark amount corresponds to a partial transition
mDarkController.setDarkAmount(0.9f);
// THEN views should have intermediate alpha value.
assertThat(mViewFadeIn.getAlpha()).isGreaterThan(0f);
assertThat(mViewFadeIn.getAlpha()).isLessThan(1f);
assertThat(mViewFadeIn.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void setDarkAmount_partialFadeOut() {
// WHEN dark amount corresponds to a partial transition
mDarkController.setDarkAmount(0.1f);
// THEN views should have intermediate alpha value.
assertThat(mViewFadeOut.getAlpha()).isGreaterThan(0f);
assertThat(mViewFadeOut.getAlpha()).isLessThan(1f);
assertThat(mViewFadeOut.getVisibility()).isEqualTo(View.VISIBLE);
}
}