1 /*
2  * Copyright (C) 2020 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.shared.recents.utilities;
18 
19 import android.graphics.Bitmap;
20 import android.graphics.ColorSpace;
21 import android.graphics.ParcelableColorSpace;
22 import android.hardware.HardwareBuffer;
23 import android.os.Bundle;
24 
25 import java.util.Objects;
26 
27 /**
28  * Utils for working with Bitmaps.
29  */
30 public final class BitmapUtil {
31     private static final String KEY_BUFFER = "bitmap_util_buffer";
32     private static final String KEY_COLOR_SPACE = "bitmap_util_color_space";
33 
BitmapUtil()34     private BitmapUtil(){ }
35 
36     /**
37      * Creates a Bundle that represents the given Bitmap.
38      * <p>The Bundle will contain a wrapped version of the Bitmaps HardwareBuffer, so will avoid
39      * copies when passing across processes, only pass to processes you trust.
40      *
41      * <p>Returns a new Bundle rather than modifying an exiting one to avoid key collisions, the
42      * returned Bundle should be treated as a standalone object.
43      *
44      * @param bitmap to convert to bundle
45      * @return a Bundle representing the bitmap, should only be parsed by
46      *         {@link #bundleToHardwareBitmap(Bundle)}
47      */
hardwareBitmapToBundle(Bitmap bitmap)48     public static Bundle hardwareBitmapToBundle(Bitmap bitmap) {
49         if (bitmap.getConfig() != Bitmap.Config.HARDWARE) {
50             throw new IllegalArgumentException(
51                     "Passed bitmap must have hardware config, found: " + bitmap.getConfig());
52         }
53 
54         // Bitmap assumes SRGB for null color space
55         ParcelableColorSpace colorSpace =
56                 bitmap.getColorSpace() == null
57                         ? new ParcelableColorSpace(ColorSpace.get(ColorSpace.Named.SRGB))
58                         : new ParcelableColorSpace(bitmap.getColorSpace());
59 
60         Bundle bundle = new Bundle();
61         bundle.putParcelable(KEY_BUFFER, bitmap.getHardwareBuffer());
62         bundle.putParcelable(KEY_COLOR_SPACE, colorSpace);
63 
64         return bundle;
65     }
66 
67     /**
68      * Extracts the Bitmap added to a Bundle with {@link #hardwareBitmapToBundle(Bitmap)} .}
69      *
70      * <p>This Bitmap contains the HardwareBuffer from the original caller, be careful passing this
71      * Bitmap on to any other source.
72      *
73      * @param bundle containing the bitmap
74      * @return a hardware Bitmap
75      */
bundleToHardwareBitmap(Bundle bundle)76     public static Bitmap bundleToHardwareBitmap(Bundle bundle) {
77         if (!bundle.containsKey(KEY_BUFFER) || !bundle.containsKey(KEY_COLOR_SPACE)) {
78             throw new IllegalArgumentException("Bundle does not contain a hardware bitmap");
79         }
80 
81         HardwareBuffer buffer = bundle.getParcelable(KEY_BUFFER);
82         ParcelableColorSpace colorSpace = bundle.getParcelable(KEY_COLOR_SPACE);
83 
84         return Bitmap.wrapHardwareBuffer(Objects.requireNonNull(buffer),
85                 colorSpace.getColorSpace());
86     }
87 }
88