1/*
2 * Copyright (C) 2014 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
17package com.android.systemui.statusbar;
18
19import android.content.Context;
20import android.content.res.ColorStateList;
21import android.graphics.Canvas;
22import android.graphics.PorterDuff;
23import android.graphics.drawable.Drawable;
24import android.graphics.drawable.RippleDrawable;
25import android.util.AttributeSet;
26import android.view.View;
27
28/**
29 * A view that can be used for both the dimmed and normal background of an notification.
30 */
31public class NotificationBackgroundView extends View {
32
33    private Drawable mBackground;
34    private int mClipTopAmount;
35    private int mActualHeight;
36
37    public NotificationBackgroundView(Context context, AttributeSet attrs) {
38        super(context, attrs);
39    }
40
41    @Override
42    protected void onDraw(Canvas canvas) {
43        draw(canvas, mBackground);
44    }
45
46    private void draw(Canvas canvas, Drawable drawable) {
47        if (drawable != null && mActualHeight > mClipTopAmount) {
48            drawable.setBounds(0, mClipTopAmount, getWidth(), mActualHeight);
49            drawable.draw(canvas);
50        }
51    }
52
53    @Override
54    protected boolean verifyDrawable(Drawable who) {
55        return super.verifyDrawable(who) || who == mBackground;
56    }
57
58    @Override
59    protected void drawableStateChanged() {
60        drawableStateChanged(mBackground);
61    }
62
63    private void drawableStateChanged(Drawable d) {
64        if (d != null && d.isStateful()) {
65            d.setState(getDrawableState());
66        }
67    }
68
69    @Override
70    public void drawableHotspotChanged(float x, float y) {
71        if (mBackground != null) {
72            mBackground.setHotspot(x, y);
73        }
74    }
75
76    /**
77     * Sets a background drawable. As we need to change our bounds independently of layout, we need
78     * the notion of a background independently of the regular View background..
79     */
80    public void setCustomBackground(Drawable background) {
81        if (mBackground != null) {
82            mBackground.setCallback(null);
83            unscheduleDrawable(mBackground);
84        }
85        mBackground = background;
86        if (mBackground != null) {
87            mBackground.setCallback(this);
88        }
89        if (mBackground instanceof RippleDrawable) {
90            ((RippleDrawable) mBackground).setForceSoftware(true);
91        }
92        invalidate();
93    }
94
95    public void setCustomBackground(int drawableResId) {
96        final Drawable d = mContext.getDrawable(drawableResId);
97        setCustomBackground(d);
98    }
99
100    public void setTint(int tintColor) {
101        if (tintColor != 0) {
102            mBackground.setColorFilter(tintColor, PorterDuff.Mode.SRC_ATOP);
103        } else {
104            mBackground.clearColorFilter();
105        }
106        invalidate();
107    }
108
109    public void setActualHeight(int actualHeight) {
110        mActualHeight = actualHeight;
111        invalidate();
112    }
113
114    public int getActualHeight() {
115        return mActualHeight;
116    }
117
118    public void setClipTopAmount(int clipTopAmount) {
119        mClipTopAmount = clipTopAmount;
120        invalidate();
121    }
122
123    @Override
124    public boolean hasOverlappingRendering() {
125
126        // Prevents this view from creating a layer when alpha is animating.
127        return false;
128    }
129
130    public void setState(int[] drawableState) {
131        mBackground.setState(drawableState);
132    }
133
134    public void setRippleColor(int color) {
135        if (mBackground instanceof RippleDrawable) {
136            RippleDrawable ripple = (RippleDrawable) mBackground;
137            ripple.setColor(ColorStateList.valueOf(color));
138        }
139    }
140}
141