1 /*
2  * Copyright (C) 2020 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.test.silkfx.hdr
18 
19 import android.content.Context
20 import android.graphics.Bitmap
21 import android.graphics.BlendMode
22 import android.graphics.Canvas
23 import android.graphics.LinearGradient
24 import android.graphics.Paint
25 import android.graphics.Rect
26 import android.graphics.Shader
27 import android.graphics.drawable.BitmapDrawable
28 import android.util.AttributeSet
29 import com.android.test.silkfx.common.BaseDrawingView
30 
31 class BlingyNotification : BaseDrawingView {
32 
33     private val image: Bitmap?
34     private val bounds = Rect()
35     private val paint = Paint()
36 
37     constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
38         val typed = context.obtainStyledAttributes(attrs, intArrayOf(android.R.attr.src))
39         val drawable = typed.getDrawable(0)
40         image = if (drawable is BitmapDrawable) {
41             drawable.bitmap
42         } else {
43             null
44         }
45         typed.recycle()
46     }
47 
48     override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
49         val image = image ?: return super.onMeasure(widthMeasureSpec, heightMeasureSpec)
50 
51         val widthMode = MeasureSpec.getMode(widthMeasureSpec)
52         val heightMode = MeasureSpec.getMode(heightMeasureSpec)
53 
54         // Currently only used in this mode, so that's all we'll bother to support
55         if (widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY) {
56             val width = MeasureSpec.getSize(widthMeasureSpec)
57 
58             var height = image.height * width / image.width
59             if (heightMode == MeasureSpec.AT_MOST) {
60                 height = minOf(MeasureSpec.getSize(heightMeasureSpec), height)
61             }
62             setMeasuredDimension(width, height)
63         } else {
64             super.onMeasure(widthMeasureSpec, heightMeasureSpec)
65         }
66     }
67 
68     override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
69         super.onSizeChanged(w, h, oldw, oldh)
70         bounds.set(0, 0, w, h)
71         paint.shader = LinearGradient(0f, 0f, w.toFloat(), 0f,
72                 longArrayOf(
73                         color(1f, 1f, 1f, 0f),
74                         color(1f, 1f, 1f, .1f),
75                         color(2f, 2f, 2f, .3f),
76                         color(1f, 1f, 1f, .2f),
77                         color(1f, 1f, 1f, 0f)
78                         ),
79                 floatArrayOf(.2f, .4f, .5f, .6f, .8f),
80                 Shader.TileMode.CLAMP)
81         paint.blendMode = BlendMode.PLUS
82     }
83 
84     override fun onDraw(canvas: Canvas) {
85         super.onDraw(canvas)
86 
87         val image = image ?: return
88 
89         canvas.drawBitmap(image, null, bounds, null)
90 
91         canvas.save()
92         val frac = ((drawingTime % 2000) / 300f) - 1f
93         canvas.translate(width * frac, 0f)
94         canvas.rotate(-45f)
95         canvas.drawPaint(paint)
96         canvas.restore()
97         invalidate()
98     }
99 }