Fix possible NPE in ActivityPicker.
Bug: 2325451. This change also improves the UI by returning an empty drawable of the appropriate size to make sure all labels line up correctly in the list.
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.settings;
|
package com.android.settings;
|
||||||
|
|
||||||
|
import android.graphics.ColorFilter;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import com.android.internal.app.AlertActivity;
|
import com.android.internal.app.AlertActivity;
|
||||||
import com.android.internal.app.AlertController;
|
import com.android.internal.app.AlertController;
|
||||||
@@ -349,68 +350,124 @@ public class ActivityPicker extends AlertActivity implements
|
|||||||
int width = mIconWidth;
|
int width = mIconWidth;
|
||||||
int height = mIconHeight;
|
int height = mIconHeight;
|
||||||
|
|
||||||
if (icon instanceof PaintDrawable) {
|
if (icon == null) {
|
||||||
PaintDrawable painter = (PaintDrawable) icon;
|
return new EmptyDrawable(width, height);
|
||||||
painter.setIntrinsicWidth(width);
|
|
||||||
painter.setIntrinsicHeight(height);
|
|
||||||
} else if (icon instanceof BitmapDrawable) {
|
|
||||||
// Ensure the bitmap has a density.
|
|
||||||
BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
|
|
||||||
Bitmap bitmap = bitmapDrawable.getBitmap();
|
|
||||||
if (bitmap.getDensity() == Bitmap.DENSITY_NONE) {
|
|
||||||
bitmapDrawable.setTargetDensity(mMetrics);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
int iconWidth = icon.getIntrinsicWidth();
|
|
||||||
int iconHeight = icon.getIntrinsicHeight();
|
|
||||||
|
|
||||||
if (iconWidth > 0 && iconHeight > 0) {
|
try {
|
||||||
if (width < iconWidth || height < iconHeight) {
|
if (icon instanceof PaintDrawable) {
|
||||||
final float ratio = (float) iconWidth / iconHeight;
|
PaintDrawable painter = (PaintDrawable) icon;
|
||||||
|
painter.setIntrinsicWidth(width);
|
||||||
if (iconWidth > iconHeight) {
|
painter.setIntrinsicHeight(height);
|
||||||
height = (int) (width / ratio);
|
} else if (icon instanceof BitmapDrawable) {
|
||||||
} else if (iconHeight > iconWidth) {
|
// Ensure the bitmap has a density.
|
||||||
width = (int) (height * ratio);
|
BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
|
||||||
|
Bitmap bitmap = bitmapDrawable.getBitmap();
|
||||||
|
if (bitmap.getDensity() == Bitmap.DENSITY_NONE) {
|
||||||
|
bitmapDrawable.setTargetDensity(mMetrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ?
|
|
||||||
Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
|
|
||||||
final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
|
|
||||||
final Canvas canvas = mCanvas;
|
|
||||||
canvas.setBitmap(thumb);
|
|
||||||
// Copy the old bounds to restore them later
|
|
||||||
// If we were to do oldBounds = icon.getBounds(),
|
|
||||||
// the call to setBounds() that follows would
|
|
||||||
// change the same instance and we would lose the
|
|
||||||
// old bounds
|
|
||||||
mOldBounds.set(icon.getBounds());
|
|
||||||
final int x = (mIconWidth - width) / 2;
|
|
||||||
final int y = (mIconHeight - height) / 2;
|
|
||||||
icon.setBounds(x, y, x + width, y + height);
|
|
||||||
icon.draw(canvas);
|
|
||||||
icon.setBounds(mOldBounds);
|
|
||||||
//noinspection deprecation
|
|
||||||
icon = new BitmapDrawable(thumb);
|
|
||||||
((BitmapDrawable) icon).setTargetDensity(mMetrics);
|
|
||||||
} else if (iconWidth < width && iconHeight < height) {
|
|
||||||
final Bitmap.Config c = Bitmap.Config.ARGB_8888;
|
|
||||||
final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
|
|
||||||
final Canvas canvas = mCanvas;
|
|
||||||
canvas.setBitmap(thumb);
|
|
||||||
mOldBounds.set(icon.getBounds());
|
|
||||||
final int x = (width - iconWidth) / 2;
|
|
||||||
final int y = (height - iconHeight) / 2;
|
|
||||||
icon.setBounds(x, y, x + iconWidth, y + iconHeight);
|
|
||||||
icon.draw(canvas);
|
|
||||||
icon.setBounds(mOldBounds);
|
|
||||||
//noinspection deprecation
|
|
||||||
icon = new BitmapDrawable(thumb);
|
|
||||||
((BitmapDrawable) icon).setTargetDensity(mMetrics);
|
|
||||||
}
|
}
|
||||||
|
int iconWidth = icon.getIntrinsicWidth();
|
||||||
|
int iconHeight = icon.getIntrinsicHeight();
|
||||||
|
|
||||||
|
if (iconWidth > 0 && iconHeight > 0) {
|
||||||
|
if (width < iconWidth || height < iconHeight) {
|
||||||
|
final float ratio = (float) iconWidth / iconHeight;
|
||||||
|
|
||||||
|
if (iconWidth > iconHeight) {
|
||||||
|
height = (int) (width / ratio);
|
||||||
|
} else if (iconHeight > iconWidth) {
|
||||||
|
width = (int) (height * ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ?
|
||||||
|
Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
|
||||||
|
final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
|
||||||
|
final Canvas canvas = mCanvas;
|
||||||
|
canvas.setBitmap(thumb);
|
||||||
|
// Copy the old bounds to restore them later
|
||||||
|
// If we were to do oldBounds = icon.getBounds(),
|
||||||
|
// the call to setBounds() that follows would
|
||||||
|
// change the same instance and we would lose the
|
||||||
|
// old bounds
|
||||||
|
mOldBounds.set(icon.getBounds());
|
||||||
|
final int x = (mIconWidth - width) / 2;
|
||||||
|
final int y = (mIconHeight - height) / 2;
|
||||||
|
icon.setBounds(x, y, x + width, y + height);
|
||||||
|
icon.draw(canvas);
|
||||||
|
icon.setBounds(mOldBounds);
|
||||||
|
//noinspection deprecation
|
||||||
|
icon = new BitmapDrawable(thumb);
|
||||||
|
((BitmapDrawable) icon).setTargetDensity(mMetrics);
|
||||||
|
} else if (iconWidth < width && iconHeight < height) {
|
||||||
|
final Bitmap.Config c = Bitmap.Config.ARGB_8888;
|
||||||
|
final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
|
||||||
|
final Canvas canvas = mCanvas;
|
||||||
|
canvas.setBitmap(thumb);
|
||||||
|
mOldBounds.set(icon.getBounds());
|
||||||
|
final int x = (width - iconWidth) / 2;
|
||||||
|
final int y = (height - iconHeight) / 2;
|
||||||
|
icon.setBounds(x, y, x + iconWidth, y + iconHeight);
|
||||||
|
icon.draw(canvas);
|
||||||
|
icon.setBounds(mOldBounds);
|
||||||
|
//noinspection deprecation
|
||||||
|
icon = new BitmapDrawable(thumb);
|
||||||
|
((BitmapDrawable) icon).setTargetDensity(mMetrics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Throwable t) {
|
||||||
|
icon = new EmptyDrawable(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class EmptyDrawable extends Drawable {
|
||||||
|
private final int mWidth;
|
||||||
|
private final int mHeight;
|
||||||
|
|
||||||
|
EmptyDrawable(int width, int height) {
|
||||||
|
mWidth = width;
|
||||||
|
mHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIntrinsicWidth() {
|
||||||
|
return mWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIntrinsicHeight() {
|
||||||
|
return mHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumWidth() {
|
||||||
|
return mWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumHeight() {
|
||||||
|
return mHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlpha(int alpha) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColorFilter(ColorFilter cf) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacity() {
|
||||||
|
return PixelFormat.TRANSLUCENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user