1/* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17package com.android.internal.widget; 18 19import android.annotation.Nullable; 20import android.app.Notification; 21import android.content.Context; 22import android.graphics.Bitmap; 23import android.graphics.BitmapFactory; 24import android.graphics.drawable.BitmapDrawable; 25import android.graphics.drawable.Drawable; 26import android.net.Uri; 27 28import java.io.IOException; 29import java.io.InputStream; 30 31/** 32 * A class to extract Bitmaps from a MessagingStyle message. 33 */ 34public class LocalImageResolver { 35 36 private static final int MAX_SAFE_ICON_SIZE_PX = 480; 37 38 @Nullable 39 public static Drawable resolveImage(Uri uri, Context context) throws IOException { 40 BitmapFactory.Options onlyBoundsOptions = getBoundsOptionsForImage(uri, context); 41 if ((onlyBoundsOptions.outWidth == -1) || (onlyBoundsOptions.outHeight == -1)) { 42 return null; 43 } 44 45 int originalSize = 46 (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) 47 ? onlyBoundsOptions.outHeight 48 : onlyBoundsOptions.outWidth; 49 50 double ratio = (originalSize > MAX_SAFE_ICON_SIZE_PX) 51 ? (originalSize / MAX_SAFE_ICON_SIZE_PX) 52 : 1.0; 53 54 BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); 55 bitmapOptions.inSampleSize = getPowerOfTwoForSampleRatio(ratio); 56 InputStream input = context.getContentResolver().openInputStream(uri); 57 Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions); 58 input.close(); 59 return new BitmapDrawable(context.getResources(), bitmap); 60 } 61 62 private static BitmapFactory.Options getBoundsOptionsForImage(Uri uri, Context context) 63 throws IOException { 64 InputStream input = context.getContentResolver().openInputStream(uri); 65 BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options(); 66 onlyBoundsOptions.inJustDecodeBounds = true; 67 BitmapFactory.decodeStream(input, null, onlyBoundsOptions); 68 input.close(); 69 return onlyBoundsOptions; 70 } 71 72 private static int getPowerOfTwoForSampleRatio(double ratio) { 73 int k = Integer.highestOneBit((int) Math.floor(ratio)); 74 return Math.max(1, k); 75 } 76} 77