• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.statusbar
18 
19 import android.content.Context
20 import android.graphics.Bitmap
21 import android.graphics.Canvas
22 import android.graphics.Point
23 import android.graphics.Rect
24 import android.renderscript.Allocation
25 import android.renderscript.Element
26 import android.renderscript.RenderScript
27 import android.renderscript.ScriptIntrinsicBlur
28 import android.util.MathUtils
29 import com.android.internal.graphics.ColorUtils
30 import com.android.systemui.statusbar.notification.MediaNotificationProcessor
31 
32 import javax.inject.Inject
33 import javax.inject.Singleton
34 
35 private const val COLOR_ALPHA = (255 * 0.7f).toInt()
36 private const val BLUR_RADIUS = 25f
37 private const val DOWNSAMPLE = 6
38 
39 @Singleton
40 class MediaArtworkProcessor @Inject constructor() {
41 
42     private val mTmpSize = Point()
43     private var mArtworkCache: Bitmap? = null
44 
processArtworknull45     fun processArtwork(context: Context, artwork: Bitmap): Bitmap {
46         if (mArtworkCache != null) {
47             return mArtworkCache!!
48         }
49 
50         context.display.getSize(mTmpSize)
51         val renderScript = RenderScript.create(context)
52         val rect = Rect(0, 0, artwork.width, artwork.height)
53         MathUtils.fitRect(rect, Math.max(mTmpSize.x / DOWNSAMPLE, mTmpSize.y / DOWNSAMPLE))
54         var inBitmap = Bitmap.createScaledBitmap(artwork, rect.width(), rect.height(),
55                 true /* filter */)
56         // Render script blurs only support ARGB_8888, we need a conversion if we got a
57         // different bitmap config.
58         if (inBitmap.config != Bitmap.Config.ARGB_8888) {
59             val oldIn = inBitmap
60             inBitmap = oldIn.copy(Bitmap.Config.ARGB_8888, false /* isMutable */)
61             oldIn.recycle()
62         }
63         val input = Allocation.createFromBitmap(renderScript, inBitmap,
64                 Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE)
65         val outBitmap = Bitmap.createBitmap(inBitmap.width, inBitmap.height,
66                 Bitmap.Config.ARGB_8888)
67         val output = Allocation.createFromBitmap(renderScript, outBitmap)
68         val blur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript))
69         blur.setRadius(BLUR_RADIUS)
70         blur.setInput(input)
71         blur.forEach(output)
72         output.copyTo(outBitmap)
73 
74         val swatch = MediaNotificationProcessor.findBackgroundSwatch(artwork)
75 
76         input.destroy()
77         output.destroy()
78         inBitmap.recycle()
79         blur.destroy()
80 
81         val canvas = Canvas(outBitmap)
82         canvas.drawColor(ColorUtils.setAlphaComponent(swatch.rgb, COLOR_ALPHA))
83         return outBitmap
84     }
85 
clearCachenull86     fun clearCache() {
87         mArtworkCache?.recycle()
88         mArtworkCache = null
89     }
90 }