1 /*
2  * Copyright (C) 2016 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.model;
18 
19 import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
20 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
21 import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
22 import static android.graphics.Bitmap.Config.ARGB_8888;
23 
24 import android.graphics.Bitmap;
25 import android.graphics.Color;
26 import android.graphics.Point;
27 import android.graphics.Rect;
28 import android.hardware.HardwareBuffer;
29 import android.util.Log;
30 import android.view.WindowInsetsController.Appearance;
31 import android.window.TaskSnapshot;
32 
33 import java.util.HashMap;
34 
35 /**
36  * Data for a single thumbnail.
37  */
38 public class ThumbnailData {
39 
40     public final Bitmap thumbnail;
41     public int orientation;
42     public int rotation;
43     public Rect insets;
44     public Rect letterboxInsets;
45     public boolean reducedResolution;
46     public boolean isRealSnapshot;
47     public boolean isTranslucent;
48     public int windowingMode;
49     public @Appearance int appearance;
50     public float scale;
51     public long snapshotId;
52 
ThumbnailData()53     public ThumbnailData() {
54         thumbnail = null;
55         orientation = ORIENTATION_UNDEFINED;
56         rotation = ROTATION_UNDEFINED;
57         insets = new Rect();
58         letterboxInsets = new Rect();
59         reducedResolution = false;
60         scale = 1f;
61         isRealSnapshot = true;
62         isTranslucent = false;
63         windowingMode = WINDOWING_MODE_UNDEFINED;
64         snapshotId = 0;
65     }
66 
recycleBitmap()67     public void recycleBitmap() {
68         if (thumbnail != null) {
69             thumbnail.recycle();
70         }
71     }
72 
makeThumbnail(TaskSnapshot snapshot)73     private static Bitmap makeThumbnail(TaskSnapshot snapshot) {
74         Bitmap thumbnail = null;
75         try (final HardwareBuffer buffer = snapshot.getHardwareBuffer()) {
76             if (buffer != null) {
77                 thumbnail = Bitmap.wrapHardwareBuffer(buffer, snapshot.getColorSpace());
78             }
79         } catch (IllegalArgumentException ex) {
80             // TODO(b/157562905): Workaround for a crash when we get a snapshot without this state
81             Log.e("ThumbnailData", "Unexpected snapshot without USAGE_GPU_SAMPLED_IMAGE: "
82                     + snapshot.getHardwareBuffer(), ex);
83         }
84         if (thumbnail == null) {
85             Point taskSize = snapshot.getTaskSize();
86             thumbnail = Bitmap.createBitmap(taskSize.x, taskSize.y, ARGB_8888);
87             thumbnail.eraseColor(Color.BLACK);
88         }
89         return thumbnail;
90     }
91 
wrap(int[] taskIds, TaskSnapshot[] snapshots)92     public static HashMap<Integer, ThumbnailData> wrap(int[] taskIds, TaskSnapshot[] snapshots) {
93         HashMap<Integer, ThumbnailData> temp = new HashMap<>();
94         if (taskIds == null || snapshots == null || taskIds.length != snapshots.length) {
95             return temp;
96         }
97 
98         for (int i = snapshots.length - 1; i >= 0; i--) {
99             temp.put(taskIds[i], new ThumbnailData(snapshots[i]));
100         }
101         return temp;
102     }
103 
ThumbnailData(TaskSnapshot snapshot)104     public ThumbnailData(TaskSnapshot snapshot) {
105         thumbnail = makeThumbnail(snapshot);
106         insets = new Rect(snapshot.getContentInsets());
107         letterboxInsets = new Rect(snapshot.getLetterboxInsets());
108         orientation = snapshot.getOrientation();
109         rotation = snapshot.getRotation();
110         reducedResolution = snapshot.isLowResolution();
111         // TODO(b/149579527): Pass task size instead of computing scale.
112         // Assume width and height were scaled the same; compute scale only for width
113         scale = (float) thumbnail.getWidth() / snapshot.getTaskSize().x;
114         isRealSnapshot = snapshot.isRealSnapshot();
115         isTranslucent = snapshot.isTranslucent();
116         windowingMode = snapshot.getWindowingMode();
117         appearance = snapshot.getAppearance();
118         snapshotId = snapshot.getId();
119     }
120 }
121