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