From 29007e6d69724b4125d7d38cbcef32e311dbbf3d Mon Sep 17 00:00:00 2001 From: Kunhung Li Date: Mon, 30 Jul 2018 19:30:25 +0800 Subject: [PATCH] Add clock plugin function Use clock plugin interface to replace current TextClock in keyguard Bug: 111971817 Test: atest SystemUITests Change-Id: Ib6920844700445d9cd3ffa4159cd7f630eaa853b --- .../layout/keyguard_clock_switch.xml | 38 ++++ .../layout/keyguard_presentation.xml | 17 +- .../layout/keyguard_status_view.xml | 17 +- .../android/keyguard/KeyguardClockSwitch.java | 155 ++++++++++++++++ .../android/keyguard/KeyguardStatusView.java | 7 +- .../keyguard/KeyguardClockSwitchTest.java | 169 ++++++++++++++++++ .../keyguard/KeyguardStatusViewTest.java | 3 +- 7 files changed, 374 insertions(+), 32 deletions(-) create mode 100644 packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml create mode 100644 packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java create mode 100644 packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml new file mode 100644 index 0000000000000..89b873e7ffda1 --- /dev/null +++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml @@ -0,0 +1,38 @@ + + + + + + + diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml index 87983b9186db9..a795442c62f9c 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml @@ -38,19 +38,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal|top"> - + - + mClockPluginListener = + new PluginListener() { + @Override + public void onPluginConnected(ClockPlugin plugin, Context pluginContext) { + View view = plugin.getView(); + if (view != null) { + mClockPlugin = plugin; + addView(view, -1, + new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + initPluginParams(); + mClockView.setVisibility(View.GONE); + } + } + + @Override + public void onPluginDisconnected(ClockPlugin plugin) { + View view = plugin.getView(); + if (view != null) { + mClockPlugin = null; + removeView(view); + mClockView.setVisibility(View.VISIBLE); + } + } + }; + + public KeyguardClockSwitch(Context context) { + this(context, null); + } + + public KeyguardClockSwitch(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mClockView = findViewById(R.id.default_clock_view); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + Dependency.get(PluginManager.class).addPluginListener(mClockPluginListener, + ClockPlugin.class); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + Dependency.get(PluginManager.class).removePluginListener(mClockPluginListener); + } + + /** + * It will also update plugin setStyle if plugin is connected. + */ + public void setStyle(Style style) { + mClockView.getPaint().setStyle(style); + if (mClockPlugin != null) { + mClockPlugin.setStyle(style); + } + } + + /** + * It will also update plugin setTextColor if plugin is connected. + */ + public void setTextColor(int color) { + mClockView.setTextColor(color); + if (mClockPlugin != null) { + mClockPlugin.setTextColor(color); + } + } + + public void setShowCurrentUserTime(boolean showCurrentUserTime) { + mClockView.setShowCurrentUserTime(showCurrentUserTime); + } + + public void setElegantTextHeight(boolean elegant) { + mClockView.setElegantTextHeight(elegant); + } + + public void setTextSize(int unit, float size) { + mClockView.setTextSize(unit, size); + } + + public void setFormat12Hour(CharSequence format) { + mClockView.setFormat12Hour(format); + } + + public void setFormat24Hour(CharSequence format) { + mClockView.setFormat24Hour(format); + } + + public Paint getPaint() { + return mClockView.getPaint(); + } + + public int getCurrentTextColor() { + return mClockView.getCurrentTextColor(); + } + + public float getTextSize() { + return mClockView.getTextSize(); + } + + public void refresh() { + mClockView.refresh(); + } + + /** + * When plugin changes, set all kept parameters into newer plugin. + */ + private void initPluginParams() { + if (mClockPlugin != null) { + mClockPlugin.setStyle(getPaint().getStyle()); + mClockPlugin.setTextColor(getCurrentTextColor()); + } + } + + @VisibleForTesting (otherwise = VisibleForTesting.NONE) + PluginListener getClockPluginListener() { + return mClockPluginListener; + } +} diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index 6da143c0e083a..6d1313c151067 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -39,7 +39,6 @@ import android.util.TypedValue; import android.view.View; import android.widget.GridLayout; import android.widget.RelativeLayout; -import android.widget.TextClock; import android.widget.TextView; import com.android.internal.widget.LockPatternUtils; @@ -64,7 +63,7 @@ public class KeyguardStatusView extends GridLayout implements private final float mSmallClockScale; private TextView mLogoutView; - private TextClock mClockView; + private KeyguardClockSwitch mClockView; private View mClockSeparator; private TextView mOwnerInfo; private KeyguardSliceView mKeyguardSlice; @@ -248,7 +247,7 @@ public class KeyguardStatusView extends GridLayout implements .scaleX(clockScale) .scaleY(clockScale) .withEndAction(() -> { - mClockView.getPaint().setStyle(style); + mClockView.setStyle(style); mClockView.invalidate(); }) .start(); @@ -256,7 +255,7 @@ public class KeyguardStatusView extends GridLayout implements mClockView.setY(top); mClockView.setScaleX(clockScale); mClockView.setScaleY(clockScale); - mClockView.getPaint().setStyle(style); + mClockView.setStyle(style); mClockView.invalidate(); } } else if (view == mClockSeparator) { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java new file mode 100644 index 0000000000000..e6e485740a7b4 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2018 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 static android.view.View.GONE; +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.verify; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import android.graphics.Color; +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.view.LayoutInflater; +import android.view.ViewGroup; +import android.widget.TextClock; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.ClockPlugin; +import com.android.systemui.plugins.PluginListener; +import com.android.systemui.plugins.PluginManager; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWithLooper(setAsMainLooper = true) +@RunWith(AndroidTestingRunner.class) +public class KeyguardClockSwitchTest extends SysuiTestCase { + private PluginManager mPluginManager; + + @Mock + TextClock mClockView; + @InjectMocks + KeyguardClockSwitch mKeyguardClockSwitch; + + @Before + public void setUp() { + mPluginManager = mDependency.injectMockDependency(PluginManager.class); + LayoutInflater layoutInflater = LayoutInflater.from(getContext()); + mKeyguardClockSwitch = + (KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null); + MockitoAnnotations.initMocks(this); + } + + @Test + public void onAttachToWindow_addPluginListener() { + mKeyguardClockSwitch.onAttachedToWindow(); + + ArgumentCaptor listener = ArgumentCaptor.forClass(PluginListener.class); + verify(mPluginManager).addPluginListener(listener.capture(), eq(ClockPlugin.class)); + } + + @Test + public void onDetachToWindow_removePluginListener() { + mKeyguardClockSwitch.onDetachedFromWindow(); + + ArgumentCaptor listener = ArgumentCaptor.forClass(PluginListener.class); + verify(mPluginManager).removePluginListener(listener.capture()); + } + + @Test + public void onPluginConnected_showPluginClock() { + ClockPlugin plugin = mock(ClockPlugin.class); + TextClock pluginView = new TextClock(getContext()); + when(plugin.getView()).thenReturn(pluginView); + TextPaint paint = mock(TextPaint.class); + doReturn(paint).when(mClockView).getPaint(); + PluginListener listener = mKeyguardClockSwitch.getClockPluginListener(); + + listener.onPluginConnected(plugin, null); + + verify(mClockView).setVisibility(GONE); + assertThat(plugin.getView().getParent()).isEqualTo(mKeyguardClockSwitch); + } + + @Test + public void onPluginDisconnected_showDefaultClock() { + ClockPlugin plugin = mock(ClockPlugin.class); + TextClock pluginView = new TextClock(getContext()); + when(plugin.getView()).thenReturn(pluginView); + mClockView.setVisibility(GONE); + mKeyguardClockSwitch.addView(plugin.getView(), -1, + new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + PluginListener listener = mKeyguardClockSwitch.getClockPluginListener(); + + listener.onPluginDisconnected(plugin); + + verify(mClockView).setVisibility(VISIBLE); + assertThat(plugin.getView().getParent()).isNull(); + } + + @Test + public void setTextColor_defaultClockSetTextColor() { + mKeyguardClockSwitch.setTextColor(Color.YELLOW); + + verify(mClockView).setTextColor(Color.YELLOW); + } + + @Test + public void setTextColor_pluginClockSetTextColor() { + ClockPlugin plugin = mock(ClockPlugin.class); + TextClock pluginView = new TextClock(getContext()); + when(plugin.getView()).thenReturn(pluginView); + TextPaint paint = mock(TextPaint.class); + doReturn(paint).when(mClockView).getPaint(); + PluginListener listener = mKeyguardClockSwitch.getClockPluginListener(); + listener.onPluginConnected(plugin, null); + + mKeyguardClockSwitch.setTextColor(Color.WHITE); + + 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() { + ClockPlugin plugin = mock(ClockPlugin.class); + TextClock pluginView = new TextClock(getContext()); + when(plugin.getView()).thenReturn(pluginView); + TextPaint paint = mock(TextPaint.class); + doReturn(paint).when(mClockView).getPaint(); + Style style = mock(Style.class); + PluginListener listener = mKeyguardClockSwitch.getClockPluginListener(); + listener.onPluginConnected(plugin, null); + + mKeyguardClockSwitch.setStyle(style); + + verify(plugin).setStyle(style); + } +} diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java index 1d8de2fbbccae..9e96df2c30cf1 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java @@ -22,7 +22,6 @@ import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; import android.view.LayoutInflater; -import android.widget.TextClock; import com.android.systemui.SysuiTestCase; @@ -40,7 +39,7 @@ public class KeyguardStatusViewTest extends SysuiTestCase { @Mock KeyguardSliceView mKeyguardSlice; @Mock - TextClock mClockView; + KeyguardClockSwitch mClockView; @InjectMocks KeyguardStatusView mKeyguardStatusView;