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