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 package com.android.systemui.statusbar; 17 18 import android.annotation.NonNull; 19 import android.annotation.Nullable; 20 import android.content.res.Resources; 21 import android.graphics.Canvas; 22 import android.graphics.Color; 23 import android.graphics.Paint; 24 import android.graphics.Rect; 25 import android.graphics.drawable.Drawable; 26 import android.graphics.drawable.DrawableWrapper; 27 import android.util.AttributeSet; 28 29 import com.android.systemui.R; 30 31 import org.xmlpull.v1.XmlPullParser; 32 import org.xmlpull.v1.XmlPullParserException; 33 34 import java.io.IOException; 35 36 /** 37 * The screen record drawable draws a colored background and either a countdown or circle to 38 * indicate that the screen is being recorded. 39 */ 40 public class ScreenRecordDrawable extends DrawableWrapper { 41 private Drawable mFillDrawable; 42 private Drawable mIconDrawable; 43 private int mHorizontalPadding; 44 private int mLevel; 45 private float mTextSize; 46 private int mIconRadius; 47 private int mWidthPx; 48 private int mHeightPx; 49 private Paint mPaint; 50 51 /** No-arg constructor used by drawable inflation. */ ScreenRecordDrawable()52 public ScreenRecordDrawable() { 53 super(null); 54 } 55 56 @Override inflate(@onNull Resources r, @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Resources.Theme theme)57 public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser, 58 @NonNull AttributeSet attrs, @Nullable Resources.Theme theme) 59 throws XmlPullParserException, IOException { 60 super.inflate(r, parser, attrs, theme); 61 setDrawable(r.getDrawable(R.drawable.ic_screen_record_background, theme).mutate()); 62 mFillDrawable = r.getDrawable(R.drawable.ic_screen_record_background, theme).mutate(); 63 mIconDrawable = r.getDrawable(R.drawable.ic_screenrecord, theme).mutate(); 64 mHorizontalPadding = r.getDimensionPixelSize(R.dimen.status_bar_horizontal_padding); 65 66 mTextSize = r.getDimensionPixelSize(R.dimen.screenrecord_status_text_size); 67 mIconRadius = r.getDimensionPixelSize(R.dimen.screenrecord_status_icon_radius); 68 mLevel = attrs.getAttributeIntValue(null, "level", 0); 69 70 mPaint = new Paint(); 71 mPaint.setTextAlign(Paint.Align.CENTER); 72 mPaint.setColor(Color.WHITE); 73 mPaint.setTextSize(mTextSize); 74 mPaint.setFakeBoldText(true); 75 76 mWidthPx = r.getDimensionPixelSize(R.dimen.screenrecord_status_icon_width); 77 mHeightPx = r.getDimensionPixelSize(R.dimen.screenrecord_status_icon_height); 78 } 79 80 @Override getIntrinsicWidth()81 public int getIntrinsicWidth() { 82 return mWidthPx; 83 } 84 85 @Override getIntrinsicHeight()86 public int getIntrinsicHeight() { 87 return mHeightPx; 88 } 89 90 @Override canApplyTheme()91 public boolean canApplyTheme() { 92 return mFillDrawable.canApplyTheme() || super.canApplyTheme(); 93 } 94 95 @Override applyTheme(Resources.Theme t)96 public void applyTheme(Resources.Theme t) { 97 super.applyTheme(t); 98 mFillDrawable.applyTheme(t); 99 } 100 101 @Override onBoundsChange(Rect bounds)102 protected void onBoundsChange(Rect bounds) { 103 super.onBoundsChange(bounds); 104 mFillDrawable.setBounds(bounds); 105 } 106 107 @Override onLayoutDirectionChanged(int layoutDirection)108 public boolean onLayoutDirectionChanged(int layoutDirection) { 109 mFillDrawable.setLayoutDirection(layoutDirection); 110 return super.onLayoutDirectionChanged(layoutDirection); 111 } 112 113 @Override draw(Canvas canvas)114 public void draw(Canvas canvas) { 115 super.draw(canvas); 116 mFillDrawable.draw(canvas); 117 118 Rect b = mFillDrawable.getBounds(); 119 if (mLevel > 0) { 120 String val = String.valueOf(mLevel); 121 Rect textBounds = new Rect(); 122 mPaint.getTextBounds(val, 0, val.length(), textBounds); 123 canvas.drawText(val, b.centerX(), b.centerY() + textBounds.height() / 2, mPaint); 124 } else { 125 Rect iconBounds = new Rect(b.centerX() - mIconRadius, 126 b.centerY() - mIconRadius, 127 b.centerX() + mIconRadius, 128 b.centerY() + mIconRadius); 129 mIconDrawable.setBounds(iconBounds); 130 mIconDrawable.draw(canvas); 131 } 132 } 133 134 @Override getPadding(Rect padding)135 public boolean getPadding(Rect padding) { 136 padding.left += mHorizontalPadding; 137 padding.right += mHorizontalPadding; 138 return true; 139 } 140 141 @Override setAlpha(int alpha)142 public void setAlpha(int alpha) { 143 super.setAlpha(alpha); 144 mFillDrawable.setAlpha(alpha); 145 } 146 147 @Override setVisible(boolean visible, boolean restart)148 public boolean setVisible(boolean visible, boolean restart) { 149 mFillDrawable.setVisible(visible, restart); 150 return super.setVisible(visible, restart); 151 } 152 153 @Override mutate()154 public Drawable mutate() { 155 mFillDrawable.mutate(); 156 return super.mutate(); 157 } 158 } 159