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 package com.android.systemui.statusbar.notification.stack
17 
18 import android.animation.AnimatorListenerAdapter
19 import android.content.Context
20 import android.content.res.Configuration
21 import android.graphics.Canvas
22 import android.graphics.Path
23 import android.graphics.RectF
24 import android.util.AttributeSet
25 import com.android.systemui.R
26 import com.android.systemui.statusbar.notification.row.ExpandableView
27 
28 /**
29  * Root view to insert Lock screen media controls into the notification stack.
30  */
31 class MediaContainerView(context: Context, attrs: AttributeSet?) : ExpandableView(context, attrs) {
32 
33     override var clipHeight = 0
34     var cornerRadius = 0f
35     var clipRect = RectF()
36     var clipPath = Path()
37 
38     init {
39         setWillNotDraw(false) // Run onDraw after invalidate.
40         updateResources()
41     }
42 
43     override fun onConfigurationChanged(newConfig: Configuration?) {
44         super.onConfigurationChanged(newConfig)
45         updateResources()
46     }
47 
48     private fun updateResources() {
49         cornerRadius = context.resources
50                 .getDimensionPixelSize(R.dimen.notification_corner_radius).toFloat()
51     }
52 
53     public override fun updateClipping() {
54         if (clipHeight != actualHeight) {
55             clipHeight = actualHeight
56         }
57         invalidate()
58     }
59 
60     override fun onDraw(canvas: Canvas) {
61         super.onDraw(canvas)
62 
63         val bounds = canvas.clipBounds
64         bounds.bottom = clipHeight
65         clipRect.set(bounds)
66 
67         clipPath.reset()
68         clipPath.addRoundRect(clipRect, cornerRadius, cornerRadius, Path.Direction.CW)
69         canvas.clipPath(clipPath)
70     }
71 
72     override fun performRemoveAnimation(
73             duration: Long,
74             delay: Long,
75             translationDirection: Float,
76             isHeadsUpAnimation: Boolean,
77             onFinishedRunnable: Runnable?,
78             animationListener: AnimatorListenerAdapter?
79     ): Long {
80         return 0
81     }
82 
83     override fun performAddAnimation(delay: Long, duration: Long, isHeadsUpAppear: Boolean,
84                                      onEnd: Runnable?) {
85         // No animation, it doesn't need it, this would be local
86     }
87 }