1e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato/* 2e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Copyright (C) 2008 The Android Open Source Project 3e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * 4e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 5e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * you may not use this file except in compliance with the License. 6e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * You may obtain a copy of the License at 7e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * 8e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * http://www.apache.org/licenses/LICENSE-2.0 9e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * 10e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Unless required by applicable law or agreed to in writing, software 11e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 12e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * See the License for the specific language governing permissions and 14e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * limitations under the License. 15e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato */ 16e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 17b10e33ff804a831c71be9303146cea892b9aeb5dJorim Jaggipackage com.android.server.policy; 18e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 19e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.drawable.BitmapDrawable; 20e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.drawable.Drawable; 21e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.drawable.PaintDrawable; 22e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.drawable.StateListDrawable; 23e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.Bitmap; 24e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.BlurMaskFilter; 25e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.Canvas; 26e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.ColorMatrix; 27e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.Paint; 28e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.PaintFlagsDrawFilter; 29e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.PorterDuff; 30e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.Rect; 31e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.TableMaskFilter; 32e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.util.DisplayMetrics; 3368b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brownimport android.util.TypedValue; 34e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.content.res.Resources; 35e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.content.Context; 36e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 37e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato/** 38e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Various utilities shared amongst the Launcher's classes. 39e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato */ 40d09020576f4ae19b006983bc0eab5c317a8856deRubin Xupublic final class IconUtilities { 41e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private static final String TAG = "IconUtilities"; 42e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 43e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private static final int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff }; 44e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 45e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private int mIconWidth = -1; 46e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private int mIconHeight = -1; 47e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private int mIconTextureWidth = -1; 48e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private int mIconTextureHeight = -1; 49e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 50e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private final Paint mPaint = new Paint(); 51e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private final Paint mBlurPaint = new Paint(); 52e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private final Paint mGlowColorPressedPaint = new Paint(); 53e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private final Paint mGlowColorFocusedPaint = new Paint(); 54e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private final Rect mOldBounds = new Rect(); 55e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private final Canvas mCanvas = new Canvas(); 56e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private final DisplayMetrics mDisplayMetrics; 57e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 58e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private int mColorIndex = 0; 59e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 60e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato public IconUtilities(Context context) { 61e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final Resources resources = context.getResources(); 62e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato DisplayMetrics metrics = mDisplayMetrics = resources.getDisplayMetrics(); 63e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final float density = metrics.density; 64e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final float blurPx = 5 * density; 65e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 66e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mIconWidth = mIconHeight = (int) resources.getDimension(android.R.dimen.app_icon_size); 67e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2); 68e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 69e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL)); 7068b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown 7168b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown TypedValue value = new TypedValue(); 7268b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown mGlowColorPressedPaint.setColor(context.getTheme().resolveAttribute( 7368b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown android.R.attr.colorPressedHighlight, value, true) ? value.data : 0xffffc300); 74e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); 7568b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown mGlowColorFocusedPaint.setColor(context.getTheme().resolveAttribute( 7668b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown android.R.attr.colorFocusedHighlight, value, true) ? value.data : 0xffff8e00); 77e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); 78e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 79e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato ColorMatrix cm = new ColorMatrix(); 80e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato cm.setSaturation(0.2f); 81e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 82e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, 83e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Paint.FILTER_BITMAP_FLAG)); 84e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 85e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 86e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato public Drawable createIconDrawable(Drawable src) { 87e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Bitmap scaled = createIconBitmap(src); 88e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 89e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato StateListDrawable result = new StateListDrawable(); 90e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 91e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato result.addState(new int[] { android.R.attr.state_focused }, 92e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato new BitmapDrawable(createSelectedBitmap(scaled, false))); 93e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato result.addState(new int[] { android.R.attr.state_pressed }, 94e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato new BitmapDrawable(createSelectedBitmap(scaled, true))); 95e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato result.addState(new int[0], new BitmapDrawable(scaled)); 96e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 97e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato result.setBounds(0, 0, mIconTextureWidth, mIconTextureHeight); 98e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato return result; 99e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 100e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 101e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato /** 102e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Returns a bitmap suitable for the all apps view. The bitmap will be a power 103e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * of two sized ARGB_8888 bitmap that can be used as a gl texture. 104e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato */ 105d09020576f4ae19b006983bc0eab5c317a8856deRubin Xu public Bitmap createIconBitmap(Drawable icon) { 106e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato int width = mIconWidth; 107e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato int height = mIconHeight; 108e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 109e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (icon instanceof PaintDrawable) { 110e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato PaintDrawable painter = (PaintDrawable) icon; 111e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato painter.setIntrinsicWidth(width); 112e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato painter.setIntrinsicHeight(height); 113e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } else if (icon instanceof BitmapDrawable) { 114e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // Ensure the bitmap has a density. 115e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; 116e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Bitmap bitmap = bitmapDrawable.getBitmap(); 117e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (bitmap.getDensity() == Bitmap.DENSITY_NONE) { 118e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato bitmapDrawable.setTargetDensity(mDisplayMetrics); 119e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 120e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 121e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato int sourceWidth = icon.getIntrinsicWidth(); 122e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato int sourceHeight = icon.getIntrinsicHeight(); 123e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 1248108e9f8cd03b97a81dbae83ec7164dcb93b515aSeongJae Park if (sourceWidth > 0 && sourceHeight > 0) { 125e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // There are intrinsic sizes. 126e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (width < sourceWidth || height < sourceHeight) { 127e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // It's too big, scale it down. 128e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final float ratio = (float) sourceWidth / sourceHeight; 129e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (sourceWidth > sourceHeight) { 130e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato height = (int) (width / ratio); 131e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } else if (sourceHeight > sourceWidth) { 132e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato width = (int) (height * ratio); 133e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 134e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } else if (sourceWidth < width && sourceHeight < height) { 135e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // It's small, use the size they gave us. 136e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato width = sourceWidth; 137e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato height = sourceHeight; 138e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 139e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 140e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 141e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // no intrinsic size --> use default size 142e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato int textureWidth = mIconTextureWidth; 143e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato int textureHeight = mIconTextureHeight; 144e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 145e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight, 146e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Bitmap.Config.ARGB_8888); 147e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final Canvas canvas = mCanvas; 148e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato canvas.setBitmap(bitmap); 149e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 150e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final int left = (textureWidth-width) / 2; 151e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final int top = (textureHeight-height) / 2; 152e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 153e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (false) { 154e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // draw a big box for the icon for debugging 155e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato canvas.drawColor(sColors[mColorIndex]); 156e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (++mColorIndex >= sColors.length) mColorIndex = 0; 157e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Paint debugPaint = new Paint(); 158e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato debugPaint.setColor(0xffcccc00); 159e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato canvas.drawRect(left, top, left+width, top+height, debugPaint); 160e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 161e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 162e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mOldBounds.set(icon.getBounds()); 163e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato icon.setBounds(left, top, left+width, top+height); 164e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato icon.draw(canvas); 165e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato icon.setBounds(mOldBounds); 166e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 167e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato return bitmap; 168e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 169e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 170e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private Bitmap createSelectedBitmap(Bitmap src, boolean pressed) { 171e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final Bitmap result = Bitmap.createBitmap(mIconTextureWidth, mIconTextureHeight, 172e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Bitmap.Config.ARGB_8888); 173e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final Canvas dest = new Canvas(result); 174e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 175e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato dest.drawColor(0, PorterDuff.Mode.CLEAR); 176e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 177e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato int[] xy = new int[2]; 178e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Bitmap mask = src.extractAlpha(mBlurPaint, xy); 179e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 180e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato dest.drawBitmap(mask, xy[0], xy[1], 181e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato pressed ? mGlowColorPressedPaint : mGlowColorFocusedPaint); 182e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 183e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mask.recycle(); 184e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 185e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato dest.drawBitmap(src, 0, 0, mPaint); 1866311d0a079702b29984c0d31937345be105e1a5eDianne Hackborn dest.setBitmap(null); 187e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 188e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato return result; 189e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 190e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato} 191