1f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell/* 2f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * Copyright (C) 2014 The Android Open Source Project 3f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * 4f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 5f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * you may not use this file except in compliance with the License. 6f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * You may obtain a copy of the License at 7f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * 8f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * http://www.apache.org/licenses/LICENSE-2.0 9f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * 10f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * Unless required by applicable law or agreed to in writing, software 11f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * distributed under the License is distributed on an "AS IS" BASIS, 12f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * See the License for the specific language governing permissions and 14f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * limitations under the License. 15f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell */ 16f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell 17f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell 18f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellpackage com.android.internal.widget; 19f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell 20f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellimport android.graphics.Canvas; 21f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellimport android.graphics.PixelFormat; 22f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellimport android.graphics.drawable.Drawable; 23f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellimport android.view.View; 24f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellimport android.view.ViewGroup; 25f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell 26f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell/** 27f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * Helper class for drawing a fallback background in framework decor layouts. 28f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * Useful for when an app has not set a window background but we're asked to draw 29f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * an uncovered area. 30f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell */ 31f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellpublic class BackgroundFallback { 32f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell private Drawable mBackgroundFallback; 33f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell 34f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell public void setDrawable(Drawable d) { 35f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell mBackgroundFallback = d; 36f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 37f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell 38f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell public boolean hasFallback() { 39f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell return mBackgroundFallback != null; 40f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 41f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell 42853d17d838ca53dcafabaf62f45518bbf58622c7Jorim Jaggi /** 43853d17d838ca53dcafabaf62f45518bbf58622c7Jorim Jaggi * Draws the fallback background. 44853d17d838ca53dcafabaf62f45518bbf58622c7Jorim Jaggi * 45853d17d838ca53dcafabaf62f45518bbf58622c7Jorim Jaggi * @param boundsView The view determining with which bounds the background should be drawn. 46853d17d838ca53dcafabaf62f45518bbf58622c7Jorim Jaggi * @param root The view group containing the content. 47853d17d838ca53dcafabaf62f45518bbf58622c7Jorim Jaggi * @param c The canvas to draw the background onto. 48853d17d838ca53dcafabaf62f45518bbf58622c7Jorim Jaggi * @param content The view where the actual app content is contained in. 49853d17d838ca53dcafabaf62f45518bbf58622c7Jorim Jaggi */ 50853d17d838ca53dcafabaf62f45518bbf58622c7Jorim Jaggi public void draw(ViewGroup boundsView, ViewGroup root, Canvas c, View content) { 51f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell if (!hasFallback()) { 52f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell return; 53f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 54f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell 55f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell // Draw the fallback in the padding. 56853d17d838ca53dcafabaf62f45518bbf58622c7Jorim Jaggi final int width = boundsView.getWidth(); 57853d17d838ca53dcafabaf62f45518bbf58622c7Jorim Jaggi final int height = boundsView.getHeight(); 58f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell int left = width; 59f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell int top = height; 60f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell int right = 0; 61f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell int bottom = 0; 62f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell 63f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell final int childCount = root.getChildCount(); 64f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell for (int i = 0; i < childCount; i++) { 65f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell final View child = root.getChildAt(i); 66f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell final Drawable childBg = child.getBackground(); 67f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell if (child == content) { 68f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell // We always count the content view container unless it has no background 69f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell // and no children. 70f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell if (childBg == null && child instanceof ViewGroup && 71f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell ((ViewGroup) child).getChildCount() == 0) { 72f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell continue; 73f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 74f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } else if (child.getVisibility() != View.VISIBLE || childBg == null || 75f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell childBg.getOpacity() != PixelFormat.OPAQUE) { 76f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell // Potentially translucent or invisible children don't count, and we assume 77f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell // the content view will cover the whole area if we're in a background 78f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell // fallback situation. 79f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell continue; 80f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 81f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell left = Math.min(left, child.getLeft()); 82f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell top = Math.min(top, child.getTop()); 83f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell right = Math.max(right, child.getRight()); 84f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell bottom = Math.max(bottom, child.getBottom()); 85f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 86f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell 87f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell if (left >= right || top >= bottom) { 88f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell // No valid area to draw in. 89f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell return; 90f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 91f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell 92f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell if (top > 0) { 93f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell mBackgroundFallback.setBounds(0, 0, width, top); 94f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell mBackgroundFallback.draw(c); 95f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 96f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell if (left > 0) { 97f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell mBackgroundFallback.setBounds(0, top, left, height); 98f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell mBackgroundFallback.draw(c); 99f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 100f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell if (right < width) { 101f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell mBackgroundFallback.setBounds(right, top, width, height); 102f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell mBackgroundFallback.draw(c); 103f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 104f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell if (bottom < height) { 105f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell mBackgroundFallback.setBounds(left, bottom, right, height); 106f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell mBackgroundFallback.draw(c); 107f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 108f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell } 109f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell} 110