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