1 /*
2  * Copyright (c) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.shade;
18 
19 import android.annotation.NonNull;
20 import android.graphics.Canvas;
21 import android.graphics.Color;
22 import android.graphics.ColorFilter;
23 import android.graphics.Paint;
24 import android.graphics.PixelFormat;
25 import android.graphics.drawable.Drawable;
26 
27 import com.android.keyguard.LockIconViewController;
28 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
29 
30 import java.util.HashSet;
31 import java.util.Set;
32 
33 /**
34  * Drawable for NotificationPanelViewController.
35  */
36 public class DebugDrawable extends Drawable {
37 
38     private final NotificationPanelViewController mNotificationPanelViewController;
39     private final NotificationPanelView mView;
40     private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
41     private final LockIconViewController mLockIconViewController;
42     private final QuickSettingsController mQsController;
43     private final Set<Integer> mDebugTextUsedYPositions;
44     private final Paint mDebugPaint;
45 
DebugDrawable( NotificationPanelViewController notificationPanelViewController, NotificationPanelView notificationPanelView, NotificationStackScrollLayoutController notificationStackScrollLayoutController, LockIconViewController lockIconViewController, QuickSettingsController quickSettingsController )46     public DebugDrawable(
47             NotificationPanelViewController notificationPanelViewController,
48             NotificationPanelView notificationPanelView,
49             NotificationStackScrollLayoutController notificationStackScrollLayoutController,
50             LockIconViewController lockIconViewController,
51             QuickSettingsController quickSettingsController
52     ) {
53         mNotificationPanelViewController = notificationPanelViewController;
54         mView = notificationPanelView;
55         mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
56         mLockIconViewController = lockIconViewController;
57         mQsController = quickSettingsController;
58         mDebugTextUsedYPositions = new HashSet<>();
59         mDebugPaint = new Paint();
60     }
61 
62     @Override
draw(@ndroidx.annotation.NonNull @onNull Canvas canvas)63     public void draw(@androidx.annotation.NonNull @NonNull Canvas canvas) {
64         mDebugTextUsedYPositions.clear();
65 
66         mDebugPaint.setColor(Color.RED);
67         mDebugPaint.setStrokeWidth(2);
68         mDebugPaint.setStyle(Paint.Style.STROKE);
69         mDebugPaint.setTextSize(24);
70         String headerDebugInfo = mNotificationPanelViewController.getHeaderDebugInfo();
71         if (headerDebugInfo != null) canvas.drawText(headerDebugInfo, 50, 100, mDebugPaint);
72 
73         drawDebugInfo(canvas, mNotificationPanelViewController.getMaxPanelHeight(),
74                 Color.RED, "getMaxPanelHeight()");
75         drawDebugInfo(canvas, (int) mNotificationPanelViewController.getExpandedHeight(),
76                 Color.BLUE, "getExpandedHeight()");
77         drawDebugInfo(canvas, mQsController.calculatePanelHeightExpanded(
78                         mNotificationPanelViewController.getClockPositionResult()
79                                 .stackScrollerPadding),
80                 Color.GREEN, "calculatePanelHeightQsExpanded()");
81         drawDebugInfo(canvas, mQsController.calculatePanelHeightExpanded(
82                         mNotificationPanelViewController.getClockPositionResult()
83                                 .stackScrollerPadding),
84                 Color.YELLOW, "calculatePanelHeightShade()");
85         drawDebugInfo(canvas,
86                 (int) mQsController.calculateNotificationsTopPadding(
87                         mNotificationPanelViewController.isExpandingOrCollapsing(),
88                         mNotificationPanelViewController.getKeyguardNotificationStaticPadding(),
89                         mNotificationPanelViewController.getExpandedFraction()),
90                 Color.MAGENTA, "calculateNotificationsTopPadding()");
91         drawDebugInfo(canvas, mNotificationPanelViewController.getClockPositionResult().clockY,
92                 Color.GRAY, "mClockPositionResult.clockY");
93         drawDebugInfo(canvas, (int) mLockIconViewController.getTop(), Color.GRAY,
94                 "mLockIconViewController.getTop()");
95 
96         if (mNotificationPanelViewController.isKeyguardShowing()) {
97             // Notifications have the space between those two lines.
98             drawDebugInfo(canvas,
99                     mNotificationStackScrollLayoutController.getTop()
100                             + (int) mNotificationPanelViewController
101                             .getKeyguardNotificationTopPadding(),
102                     Color.RED, "NSSL.getTop() + mKeyguardNotificationTopPadding");
103 
104             drawDebugInfo(canvas, mNotificationStackScrollLayoutController.getBottom()
105                             - (int) mNotificationPanelViewController
106                             .getKeyguardNotificationBottomPadding(),
107                     Color.RED, "NSSL.getBottom() - mKeyguardNotificationBottomPadding");
108         }
109 
110         mDebugPaint.setColor(Color.CYAN);
111         canvas.drawLine(0,
112                 mNotificationPanelViewController.getClockPositionResult().stackScrollerPadding,
113                 mView.getWidth(), mNotificationStackScrollLayoutController.getTopPadding(),
114                 mDebugPaint);
115     }
116 
drawDebugInfo(Canvas canvas, int y, int color, String label)117     private void drawDebugInfo(Canvas canvas, int y, int color, String label) {
118         mDebugPaint.setColor(color);
119         canvas.drawLine(/* startX= */ 0, /* startY= */ y, /* stopX= */ mView.getWidth(),
120                 /* stopY= */ y, mDebugPaint);
121         canvas.drawText(label + " = " + y + "px", /* x= */ 0,
122                 /* y= */ computeDebugYTextPosition(y), mDebugPaint);
123     }
124 
computeDebugYTextPosition(int lineY)125     private int computeDebugYTextPosition(int lineY) {
126         if (lineY - mDebugPaint.getTextSize() < 0) {
127             // Avoiding drawing out of bounds
128             lineY += mDebugPaint.getTextSize();
129         }
130         int textY = lineY;
131         while (mDebugTextUsedYPositions.contains(textY)) {
132             textY = (int) (textY + mDebugPaint.getTextSize());
133         }
134         mDebugTextUsedYPositions.add(textY);
135         return textY;
136     }
137 
138     @Override
setAlpha(int alpha)139     public void setAlpha(int alpha) {
140 
141     }
142 
143     @Override
setColorFilter(ColorFilter colorFilter)144     public void setColorFilter(ColorFilter colorFilter) {
145 
146     }
147 
148     @Override
getOpacity()149     public int getOpacity() {
150         return PixelFormat.UNKNOWN;
151     }
152 }
153