1a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi/*
2a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * Copyright (C) 2014 The Android Open Source Project
3a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi *
4a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License");
5a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * you may not use this file except in compliance with the License.
6a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * You may obtain a copy of the License at
7a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi *
8a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi *      http://www.apache.org/licenses/LICENSE-2.0
9a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi *
10a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * Unless required by applicable law or agreed to in writing, software
11a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS,
12a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * See the License for the specific language governing permissions and
14a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * limitations under the License
15a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi */
16a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
17a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggipackage com.android.systemui.statusbar;
18a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
19a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggiimport android.content.Context;
20697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinekimport android.content.res.ColorStateList;
21a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggiimport android.graphics.Canvas;
22a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggiimport android.graphics.PorterDuff;
23a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggiimport android.graphics.drawable.Drawable;
24697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinekimport android.graphics.drawable.RippleDrawable;
25a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggiimport android.util.AttributeSet;
26a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggiimport android.view.View;
27a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
28a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi/**
29a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * A view that can be used for both the dimmed and normal background of an notification.
30a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi */
31a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggipublic class NotificationBackgroundView extends View {
32a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
33a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    private Drawable mBackground;
34a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    private int mClipTopAmount;
35a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    private int mActualHeight;
36a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
37a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    public NotificationBackgroundView(Context context, AttributeSet attrs) {
38a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        super(context, attrs);
39a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
40a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
41a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    @Override
42a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    protected void onDraw(Canvas canvas) {
43a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        draw(canvas, mBackground);
44a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
45a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
46a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    private void draw(Canvas canvas, Drawable drawable) {
47bf3af808d0bb1a32aeb22677ebbc93507b56e7e2Selim Cinek        if (drawable != null && mActualHeight > mClipTopAmount) {
48a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi            drawable.setBounds(0, mClipTopAmount, getWidth(), mActualHeight);
49a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi            drawable.draw(canvas);
50a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        }
51a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
52a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
53a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    @Override
54a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    protected boolean verifyDrawable(Drawable who) {
55a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        return super.verifyDrawable(who) || who == mBackground;
56a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
57a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
58a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    @Override
59a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    protected void drawableStateChanged() {
60a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        drawableStateChanged(mBackground);
61a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
62a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
63a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    private void drawableStateChanged(Drawable d) {
64a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        if (d != null && d.isStateful()) {
65a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi            d.setState(getDrawableState());
66a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        }
67a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
68a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
69697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek    @Override
70697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek    public void drawableHotspotChanged(float x, float y) {
71697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek        if (mBackground != null) {
72697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek            mBackground.setHotspot(x, y);
73697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek        }
74697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek    }
75697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek
76a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    /**
77a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi     * Sets a background drawable. As we need to change our bounds independently of layout, we need
78a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi     * the notion of a background independently of the regular View background..
79a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi     */
80a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    public void setCustomBackground(Drawable background) {
81a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        if (mBackground != null) {
82a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi            mBackground.setCallback(null);
83a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi            unscheduleDrawable(mBackground);
84a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        }
85a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        mBackground = background;
86a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        if (mBackground != null) {
87a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi            mBackground.setCallback(this);
88a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        }
89b7303a36baf8d0ac3efdeeee3310ef5974ba9ceaJorim Jaggi        if (mBackground instanceof RippleDrawable) {
90b7303a36baf8d0ac3efdeeee3310ef5974ba9ceaJorim Jaggi            ((RippleDrawable) mBackground).setForceSoftware(true);
91b7303a36baf8d0ac3efdeeee3310ef5974ba9ceaJorim Jaggi        }
92a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        invalidate();
93a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
94a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
95697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek    public void setCustomBackground(int drawableResId) {
96697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek        final Drawable d = mContext.getDrawable(drawableResId);
97697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek        setCustomBackground(d);
98697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek    }
99697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek
100697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek    public void setTint(int tintColor) {
101a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        if (tintColor != 0) {
102697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek            mBackground.setColorFilter(tintColor, PorterDuff.Mode.SRC_ATOP);
103697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek        } else {
104697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek            mBackground.clearColorFilter();
105697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek        }
106697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek        invalidate();
107a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
108a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
109a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    public void setActualHeight(int actualHeight) {
110a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        mActualHeight = actualHeight;
111a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        invalidate();
112a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
113a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
114a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    public int getActualHeight() {
115a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        return mActualHeight;
116a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
117a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
118a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    public void setClipTopAmount(int clipTopAmount) {
119a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        mClipTopAmount = clipTopAmount;
120a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        invalidate();
121a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
122a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
123a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    @Override
124a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    public boolean hasOverlappingRendering() {
125a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi
126a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        // Prevents this view from creating a layer when alpha is animating.
127a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi        return false;
128a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi    }
129b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek
130b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek    public void setState(int[] drawableState) {
131b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek        mBackground.setState(drawableState);
132b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek    }
133b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek
134b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek    public void setRippleColor(int color) {
135b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek        if (mBackground instanceof RippleDrawable) {
136b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek            RippleDrawable ripple = (RippleDrawable) mBackground;
137b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek            ripple.setColor(ColorStateList.valueOf(color));
138b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek        }
139b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek    }
140a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi}
141