Implement double shadow text view for dream complications

Bug: 239089588
Test: manually on device, verifying complications are visible on white
dream

Change-Id: I9b833b6f30a4102d65d1e430a3b66ed8e79e9082
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index c827e21..75baeef 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -241,6 +241,10 @@
     <color name="dream_overlay_aqi_very_unhealthy">#AD1457</color>
     <color name="dream_overlay_aqi_hazardous">#880E4F</color>
     <color name="dream_overlay_aqi_unknown">#BDC1C6</color>
+
+    <!-- Dream overlay text shadows -->
     <color name="dream_overlay_clock_key_text_shadow_color">#4D000000</color>
     <color name="dream_overlay_clock_ambient_text_shadow_color">#4D000000</color>
+    <color name="dream_overlay_status_bar_key_text_shadow_color">#66000000</color>
+    <color name="dream_overlay_status_bar_ambient_text_shadow_color">#59000000</color>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e0264c3..d9946ff 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1547,10 +1547,20 @@
     <dimen name="broadcast_dialog_btn_text_size">16sp</dimen>
     <dimen name="broadcast_dialog_btn_minHeight">44dp</dimen>
     <dimen name="broadcast_dialog_margin">16dp</dimen>
+
+    <!-- Shadow for dream overlay clock complication -->
     <dimen name="dream_overlay_clock_key_text_shadow_dx">0dp</dimen>
     <dimen name="dream_overlay_clock_key_text_shadow_dy">0dp</dimen>
-    <dimen name="dream_overlay_clock_key_text_shadow_radius">5dp</dimen>
+    <dimen name="dream_overlay_clock_key_text_shadow_radius">3dp</dimen>
     <dimen name="dream_overlay_clock_ambient_text_shadow_dx">0dp</dimen>
     <dimen name="dream_overlay_clock_ambient_text_shadow_dy">0dp</dimen>
     <dimen name="dream_overlay_clock_ambient_text_shadow_radius">1dp</dimen>
+
+    <!-- Shadow for dream overlay status bar complications -->
+    <dimen name="dream_overlay_status_bar_key_text_shadow_dx">0.5dp</dimen>
+    <dimen name="dream_overlay_status_bar_key_text_shadow_dy">0.5dp</dimen>
+    <dimen name="dream_overlay_status_bar_key_text_shadow_radius">1dp</dimen>
+    <dimen name="dream_overlay_status_bar_ambient_text_shadow_dx">0.5dp</dimen>
+    <dimen name="dream_overlay_status_bar_ambient_text_shadow_dy">0.5dp</dimen>
+    <dimen name="dream_overlay_status_bar_ambient_text_shadow_radius">2dp</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextClock.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextClock.java
index 653f4dc..789ebc5 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextClock.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextClock.java
@@ -17,24 +17,21 @@
 package com.android.systemui.dreams.complication;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.util.AttributeSet;
 import android.widget.TextClock;
 
 import com.android.systemui.R;
+import com.android.systemui.dreams.complication.DoubleShadowTextHelper.ShadowInfo;
+
+import kotlin.Unit;
 
 /**
  * Extension of {@link TextClock} which draws two shadows on the text (ambient and key shadows)
  */
 public class DoubleShadowTextClock extends TextClock {
-    private final float mAmbientShadowBlur;
-    private final int mAmbientShadowColor;
-    private final float mKeyShadowBlur;
-    private final float mKeyShadowOffsetX;
-    private final float mKeyShadowOffsetY;
-    private final int mKeyShadowColor;
-    private final float mAmbientShadowOffsetX;
-    private final float mAmbientShadowOffsetY;
+    private final DoubleShadowTextHelper mShadowHelper;
 
     public DoubleShadowTextClock(Context context) {
         this(context, null);
@@ -46,38 +43,28 @@
 
     public DoubleShadowTextClock(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mKeyShadowBlur = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_radius);
-        mKeyShadowOffsetX = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dx);
-        mKeyShadowOffsetY = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dy);
-        mKeyShadowColor = context.getResources().getColor(
-                R.color.dream_overlay_clock_key_text_shadow_color);
-        mAmbientShadowBlur = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_radius);
-        mAmbientShadowColor = context.getResources().getColor(
-                R.color.dream_overlay_clock_ambient_text_shadow_color);
-        mAmbientShadowOffsetX = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dx);
-        mAmbientShadowOffsetY = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dy);
+
+        final Resources resources = context.getResources();
+        final ShadowInfo keyShadowInfo = new ShadowInfo(
+                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_radius),
+                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dx),
+                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dy),
+                resources.getColor(R.color.dream_overlay_clock_key_text_shadow_color));
+
+        final ShadowInfo ambientShadowInfo = new ShadowInfo(
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_clock_ambient_text_shadow_radius),
+                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dx),
+                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dy),
+                resources.getColor(R.color.dream_overlay_clock_ambient_text_shadow_color));
+        mShadowHelper = new DoubleShadowTextHelper(keyShadowInfo, ambientShadowInfo);
     }
 
     @Override
     public void onDraw(Canvas canvas) {
-        // We enhance the shadow by drawing the shadow twice
-        getPaint().setShadowLayer(mAmbientShadowBlur, mAmbientShadowOffsetX, mAmbientShadowOffsetY,
-                mAmbientShadowColor);
-        super.onDraw(canvas);
-        canvas.save();
-        canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
-                getScrollX() + getWidth(),
-                getScrollY() + getHeight());
-
-        getPaint().setShadowLayer(
-                mKeyShadowBlur, mKeyShadowOffsetX, mKeyShadowOffsetY, mKeyShadowColor);
-        super.onDraw(canvas);
-        canvas.restore();
+        mShadowHelper.applyShadows(this, canvas, () -> {
+            super.onDraw(canvas);
+            return Unit.INSTANCE;
+        });
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextHelper.kt b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextHelper.kt
new file mode 100644
index 0000000..b1dc5a2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextHelper.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 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.systemui.dreams.complication
+
+import android.graphics.Canvas
+import android.widget.TextView
+import androidx.annotation.ColorInt
+
+class DoubleShadowTextHelper
+constructor(
+    private val keyShadowInfo: ShadowInfo,
+    private val ambientShadowInfo: ShadowInfo,
+) {
+    data class ShadowInfo(
+        val blur: Float,
+        val offsetX: Float = 0f,
+        val offsetY: Float = 0f,
+        @ColorInt val color: Int
+    )
+
+    fun applyShadows(view: TextView, canvas: Canvas, onDrawCallback: () -> Unit) {
+        // We enhance the shadow by drawing the shadow twice
+        view.paint.setShadowLayer(
+            ambientShadowInfo.blur,
+            ambientShadowInfo.offsetX,
+            ambientShadowInfo.offsetY,
+            ambientShadowInfo.color
+        )
+        onDrawCallback()
+        canvas.save()
+        canvas.clipRect(
+            view.scrollX,
+            view.scrollY + view.extendedPaddingTop,
+            view.scrollX + view.width,
+            view.scrollY + view.height
+        )
+
+        view.paint.setShadowLayer(
+            keyShadowInfo.blur,
+            keyShadowInfo.offsetX,
+            keyShadowInfo.offsetY,
+            keyShadowInfo.color
+        )
+        onDrawCallback()
+        canvas.restore()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextView.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextView.java
new file mode 100644
index 0000000..cf7e312
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextView.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 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.systemui.dreams.complication;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+
+import kotlin.Unit;
+
+/**
+ * Extension of {@link TextView} which draws two shadows on the text (ambient and key shadows}
+ */
+public class DoubleShadowTextView extends TextView {
+    private final DoubleShadowTextHelper mShadowHelper;
+
+    public DoubleShadowTextView(Context context) {
+        this(context, null);
+    }
+
+    public DoubleShadowTextView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public DoubleShadowTextView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        final Resources resources = context.getResources();
+        final DoubleShadowTextHelper.ShadowInfo
+                keyShadowInfo = new DoubleShadowTextHelper.ShadowInfo(
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_key_text_shadow_radius),
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_key_text_shadow_dx),
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_key_text_shadow_dy),
+                resources.getColor(R.color.dream_overlay_status_bar_key_text_shadow_color));
+
+        final DoubleShadowTextHelper.ShadowInfo
+                ambientShadowInfo = new DoubleShadowTextHelper.ShadowInfo(
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_ambient_text_shadow_radius),
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_ambient_text_shadow_dx),
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_ambient_text_shadow_dy),
+                resources.getColor(R.color.dream_overlay_status_bar_ambient_text_shadow_color));
+        mShadowHelper = new DoubleShadowTextHelper(keyShadowInfo, ambientShadowInfo);
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        mShadowHelper.applyShadows(this, canvas, () -> {
+            super.onDraw(canvas);
+            return Unit.INSTANCE;
+        });
+    }
+}