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; 36a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek private int mClipBottomAmount; 37a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 38a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi public NotificationBackgroundView(Context context, AttributeSet attrs) { 39a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi super(context, attrs); 40a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 41a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 42a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi @Override 43a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi protected void onDraw(Canvas canvas) { 44a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi draw(canvas, mBackground); 45a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 46a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 47a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi private void draw(Canvas canvas, Drawable drawable) { 48a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek int bottom = mActualHeight - mClipBottomAmount; 49a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek if (drawable != null && bottom > mClipTopAmount) { 50a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek drawable.setBounds(0, mClipTopAmount, getWidth(), bottom); 51a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi drawable.draw(canvas); 52a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 53a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 54a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 55a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi @Override 56a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi protected boolean verifyDrawable(Drawable who) { 57a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi return super.verifyDrawable(who) || who == mBackground; 58a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 59a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 60a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi @Override 61a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi protected void drawableStateChanged() { 62a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi drawableStateChanged(mBackground); 63a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 64a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 65a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi private void drawableStateChanged(Drawable d) { 66a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi if (d != null && d.isStateful()) { 67a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi d.setState(getDrawableState()); 68a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 69a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 70a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 71697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek @Override 72697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek public void drawableHotspotChanged(float x, float y) { 73697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek if (mBackground != null) { 74697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek mBackground.setHotspot(x, y); 75697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek } 76697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek } 77697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek 78a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi /** 79a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * Sets a background drawable. As we need to change our bounds independently of layout, we need 80a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi * the notion of a background independently of the regular View background.. 81a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi */ 82a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi public void setCustomBackground(Drawable background) { 83a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi if (mBackground != null) { 84a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi mBackground.setCallback(null); 85a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi unscheduleDrawable(mBackground); 86a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 87a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi mBackground = background; 88a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi if (mBackground != null) { 89a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi mBackground.setCallback(this); 90a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 91b7303a36baf8d0ac3efdeeee3310ef5974ba9ceaJorim Jaggi if (mBackground instanceof RippleDrawable) { 92b7303a36baf8d0ac3efdeeee3310ef5974ba9ceaJorim Jaggi ((RippleDrawable) mBackground).setForceSoftware(true); 93b7303a36baf8d0ac3efdeeee3310ef5974ba9ceaJorim Jaggi } 94a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi invalidate(); 95a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 96a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 97697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek public void setCustomBackground(int drawableResId) { 98697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek final Drawable d = mContext.getDrawable(drawableResId); 99697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek setCustomBackground(d); 100697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek } 101697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek 102697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek public void setTint(int tintColor) { 103a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi if (tintColor != 0) { 104697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek mBackground.setColorFilter(tintColor, PorterDuff.Mode.SRC_ATOP); 105697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek } else { 106697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek mBackground.clearColorFilter(); 107697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek } 108697178b1244533adb0ffb3325c0a27a1fde6eacaSelim Cinek invalidate(); 109a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 110a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 111a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi public void setActualHeight(int actualHeight) { 112a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi mActualHeight = actualHeight; 113a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi invalidate(); 114a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 115a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 116a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi public int getActualHeight() { 117a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi return mActualHeight; 118a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 119a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 120a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi public void setClipTopAmount(int clipTopAmount) { 121a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi mClipTopAmount = clipTopAmount; 122a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi invalidate(); 123a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 124a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 125a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek public void setClipBottomAmount(int clipBottomAmount) { 126a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek mClipBottomAmount = clipBottomAmount; 127a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek invalidate(); 128a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek } 129a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek 130a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi @Override 131a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi public boolean hasOverlappingRendering() { 132a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi 133a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi // Prevents this view from creating a layer when alpha is animating. 134a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi return false; 135a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi } 136b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek 137b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek public void setState(int[] drawableState) { 138b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek mBackground.setState(drawableState); 139b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek } 140b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek 141b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek public void setRippleColor(int color) { 142b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek if (mBackground instanceof RippleDrawable) { 143b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek RippleDrawable ripple = (RippleDrawable) mBackground; 144b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek ripple.setColor(ColorStateList.valueOf(color)); 145b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek } 146b2da91b14fb8ad15a74d171a298649e8cb6322bbSelim Cinek } 147ec29d34e0ba54e50fc3110c137a3197c92ba1a5fSelim Cinek 148ec29d34e0ba54e50fc3110c137a3197c92ba1a5fSelim Cinek public void setDrawableAlpha(int drawableAlpha) { 149ec29d34e0ba54e50fc3110c137a3197c92ba1a5fSelim Cinek mBackground.setAlpha(drawableAlpha); 150ec29d34e0ba54e50fc3110c137a3197c92ba1a5fSelim Cinek } 151a8b48e166ca037b3b0be2f4868e6b70fdba19d9dJorim Jaggi} 152