Add option for plugins to hide KeyguardSliceView.

Option defaults to showing the slice view so that it doesn't break
existing plugins.

Test: SystemUIGoogleTests pass.
Test: SystemUITests pass.
Test: slice view is hidden when using example plugin.
Bug: 118496011
Change-Id: I574009170da4703e84fd392e327e1cb84ada6cd0
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
index 1a18f60..6135aeb 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
@@ -62,4 +62,12 @@
      * Notifies that the time zone has changed.
      */
     default void onTimeZoneChanged(TimeZone timeZone) {}
+
+    /**
+     * Indicates whether the keyguard status area (date) should be shown below
+     * the clock.
+     */
+    default boolean shouldShowStatusArea() {
+        return true;
+    }
 }
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index 367a9ae..d52866f 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -20,19 +20,31 @@
 <!-- This is a view that shows clock information in Keyguard. -->
 <com.android.keyguard.KeyguardClockSwitch
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/keyguard_clock_container"
     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="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="wrap_content"
+             android:layout_height="wrap_content"
+             android:layout_gravity="center_horizontal"
+             android:letterSpacing="0.03"
+             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" />
+    </FrameLayout>
+    <include layout="@layout/keyguard_status_area"
+        android:id="@+id/keyguard_status_area"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal"
-        android:letterSpacing="0.03"
-        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:layout_below="@id/clock_view" />
 </com.android.keyguard.KeyguardClockSwitch>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
index 7d8a1f5b..a9ba19d 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
@@ -33,21 +33,11 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical">
-            <RelativeLayout
+            <include
+                layout="@layout/keyguard_clock_switch"
                 android:id="@+id/keyguard_clock_container"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_horizontal|top">
-                <include layout="@layout/keyguard_clock_switch"
-                         android:id="@+id/clock_view"
-                         android:layout_width="match_parent"
-                         android:layout_height="wrap_content" />
-                <include layout="@layout/keyguard_status_area"
-                         android:id="@+id/keyguard_status_area"
-                         android:layout_width="match_parent"
-                         android:layout_height="wrap_content"
-                         android:layout_below="@id/clock_view" />
-            </RelativeLayout>
+                android:layout_height="wrap_content" />
             <ImageView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 67ecf6f..10fea9d 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -50,21 +50,11 @@
             android:textSize="13sp"
             android:text="@*android:string/global_action_logout" />
 
-        <RelativeLayout
+        <include
+            layout="@layout/keyguard_clock_switch"
             android:id="@+id/keyguard_clock_container"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal|top">
-            <include layout="@layout/keyguard_clock_switch"
-                 android:id="@+id/clock_view"
-                 android:layout_width="match_parent"
-                 android:layout_height="wrap_content" />
-            <include layout="@layout/keyguard_status_area"
-                android:id="@+id/keyguard_status_area"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_below="@id/clock_view" />
-        </RelativeLayout>
+            android:layout_height="wrap_content" />
 
         <TextView
             android:id="@+id/owner_info"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 0ec9014..22a23a8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -7,6 +7,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
+import android.widget.RelativeLayout;
 import android.widget.TextClock;
 
 import androidx.annotation.VisibleForTesting;
@@ -22,7 +23,7 @@
 /**
  * Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
  */
-public class KeyguardClockSwitch extends FrameLayout {
+public class KeyguardClockSwitch extends RelativeLayout {
     /**
      * Optional/alternative clock injected via plugin.
      */
@@ -31,6 +32,15 @@
      * Default clock.
      */
     private TextClock mClockView;
+    /**
+     * Frame for default and custom clock.
+     */
+    private FrameLayout mClockFrame;
+    /**
+     * Status area (date and other stuff) shown below the clock. Plugin can decide whether
+     * or not to show it below the alternate clock.
+     */
+    private View mKeyguardStatusArea;
 
     private final PluginListener<ClockPlugin> mClockPluginListener =
             new PluginListener<ClockPlugin>() {
@@ -43,11 +53,14 @@
                         // selected clock face. In the future, the user should be able to
                         // pick a clock face from the available plugins.
                         mClockPlugin = plugin;
-                        addView(view, -1,
+                        mClockFrame.addView(view, -1,
                                 new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                         ViewGroup.LayoutParams.WRAP_CONTENT));
                         initPluginParams();
                         mClockView.setVisibility(View.GONE);
+                        if (!plugin.shouldShowStatusArea()) {
+                            mKeyguardStatusArea.setVisibility(View.GONE);
+                        }
                     }
                 }
 
@@ -56,6 +69,7 @@
                     if (Objects.equals(plugin, mClockPlugin)) {
                         disconnectPlugin();
                         mClockView.setVisibility(View.VISIBLE);
+                        mKeyguardStatusArea.setVisibility(View.VISIBLE);
                     }
                 }
             };
@@ -72,6 +86,8 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mClockView = findViewById(R.id.default_clock_view);
+        mClockFrame = findViewById(R.id.clock_view);
+        mKeyguardStatusArea = findViewById(R.id.keyguard_status_area);
     }
 
     @Override
@@ -185,7 +201,7 @@
         if (mClockPlugin != null) {
             View view = mClockPlugin.getView();
             if (view != null) {
-                removeView(view);
+                mClockFrame.removeView(view);
             }
             mClockPlugin = null;
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 1e9d288..c6f1726 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -37,7 +37,7 @@
 import android.util.TypedValue;
 import android.view.View;
 import android.widget.GridLayout;
-import android.widget.RelativeLayout;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import androidx.core.graphics.ColorUtils;
@@ -173,7 +173,7 @@
             mLogoutView.setOnClickListener(this::onLogoutClicked);
         }
 
-        mClockView = findViewById(R.id.clock_view);
+        mClockView = findViewById(R.id.keyguard_clock_container);
         mClockView.setShowCurrentUserTime(true);
         if (KeyguardClockAccessibilityDelegate.isNeeded(mContext)) {
             mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
@@ -205,8 +205,8 @@
      * Moves clock, adjusting margins when slice content changes.
      */
     private void onSliceContentChanged() {
-        RelativeLayout.LayoutParams layoutParams =
-                (RelativeLayout.LayoutParams) mClockView.getLayoutParams();
+        LinearLayout.LayoutParams layoutParams =
+                (LinearLayout.LayoutParams) mClockView.getLayoutParams();
         layoutParams.bottomMargin = mPulsing ? mSmallClockPadding : 0;
         mClockView.setLayoutParams(layoutParams);
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 7ca5423..fb2ceac 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -35,6 +35,7 @@
 import android.testing.TestableLooper.RunWithLooper;
 import android.text.TextPaint;
 import android.view.LayoutInflater;
+import android.widget.FrameLayout;
 import android.widget.TextClock;
 
 import com.android.systemui.SysuiTestCase;
@@ -51,10 +52,14 @@
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
-@RunWithLooper
 @RunWith(AndroidTestingRunner.class)
+// Need to run on the main thread because KeyguardSliceView$Row init checks for
+// the main thread before acquiring a wake lock. This class is constructed when
+// the keyguard_clcok_switch layout is inflated.
+@RunWithLooper(setAsMainLooper = true)
 public class KeyguardClockSwitchTest extends SysuiTestCase {
     private PluginManager mPluginManager;
+    private FrameLayout mClockContainer;
 
     @Mock
     TextClock mClockView;
@@ -67,6 +72,7 @@
         LayoutInflater layoutInflater = LayoutInflater.from(getContext());
         mKeyguardClockSwitch =
                 (KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null);
+        mClockContainer = mKeyguardClockSwitch.findViewById(R.id.clock_view);
         MockitoAnnotations.initMocks(this);
         when(mClockView.getPaint()).thenReturn(mock(TextPaint.class));
     }
@@ -97,7 +103,7 @@
         listener.onPluginConnected(plugin, null);
 
         verify(mClockView).setVisibility(GONE);
-        assertThat(plugin.getView().getParent()).isEqualTo(mKeyguardClockSwitch);
+        assertThat(plugin.getView().getParent()).isEqualTo(mClockContainer);
     }
 
     @Test
@@ -120,7 +126,7 @@
         when(plugin2.getView()).thenReturn(new TextClock(getContext()));
         listener.onPluginConnected(plugin2, null);
         // THEN only the view from the second plugin should be a child of KeyguardClockSwitch.
-        assertThat(plugin2.getView().getParent()).isEqualTo(mKeyguardClockSwitch);
+        assertThat(plugin2.getView().getParent()).isEqualTo(mClockContainer);
         assertThat(plugin1.getView().getParent()).isNull();
     }
 
@@ -161,7 +167,7 @@
         // WHEN the first plugin is disconnected
         listener.onPluginDisconnected(plugin1);
         // THEN the view from the second plugin is still a child of KeyguardClockSwitch.
-        assertThat(plugin2.getView().getParent()).isEqualTo(mKeyguardClockSwitch);
+        assertThat(plugin2.getView().getParent()).isEqualTo(mClockContainer);
         assertThat(plugin1.getView().getParent()).isNull();
     }