1 /* 2 * Copyright (C) 2021 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 17 package com.android.systemui.screenshot; 18 19 import android.annotation.Nullable; 20 import android.content.ContentResolver; 21 import android.graphics.Bitmap; 22 import android.graphics.BitmapFactory; 23 import android.net.Uri; 24 25 import androidx.concurrent.futures.CallbackToFutureAdapter; 26 27 import com.google.common.util.concurrent.ListenableFuture; 28 29 import java.io.BufferedInputStream; 30 import java.io.File; 31 import java.io.FileInputStream; 32 import java.io.IOException; 33 import java.io.InputStream; 34 35 import javax.inject.Inject; 36 37 /** Loads images. */ 38 public class ImageLoader { 39 private final ContentResolver mResolver; 40 41 static class Result { 42 @Nullable Uri uri; 43 @Nullable File fileName; 44 @Nullable Bitmap bitmap; 45 46 @Override toString()47 public String toString() { 48 final StringBuilder sb = new StringBuilder("Result{"); 49 sb.append("uri=").append(uri); 50 sb.append(", fileName=").append(fileName); 51 sb.append(", bitmap=").append(bitmap); 52 sb.append('}'); 53 return sb.toString(); 54 } 55 } 56 57 @Inject ImageLoader(ContentResolver resolver)58 ImageLoader(ContentResolver resolver) { 59 mResolver = resolver; 60 } 61 62 /** 63 * Loads an image via URI from ContentResolver. 64 * 65 * @param uri the identifier of the image to load 66 * @return a listenable future result containing a bitmap 67 */ load(Uri uri)68 ListenableFuture<Result> load(Uri uri) { 69 return CallbackToFutureAdapter.getFuture(completer -> { 70 Result result = new Result(); 71 try (InputStream in = mResolver.openInputStream(uri)) { 72 result.uri = uri; 73 result.bitmap = BitmapFactory.decodeStream(in); 74 completer.set(result); 75 } 76 catch (IOException e) { 77 completer.setException(e); 78 } 79 return "BitmapFactory#decodeStream"; 80 }); 81 } 82 83 /** 84 * Loads an image by physical filesystem name. The current user must have filesystem 85 * permissions to read this file/path. 86 * 87 * @param file the system file path of the image to load 88 * @return a listenable future result containing a bitmap 89 */ load(File file)90 ListenableFuture<Result> load(File file) { 91 return CallbackToFutureAdapter.getFuture(completer -> { 92 try (InputStream in = new BufferedInputStream(new FileInputStream(file))) { 93 Result result = new Result(); 94 result.fileName = file; 95 result.bitmap = BitmapFactory.decodeStream(in); 96 completer.set(result); 97 } catch (IOException e) { 98 completer.setException(e); 99 } 100 return "BitmapFactory#decodeStream"; 101 }); 102 } 103 } 104