TaskSnapshotLoader.java revision f3e412e5021c43491ed3ced61f02c2fd436e064e
1f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi/* 2f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * Copyright (C) 2017 The Android Open Source Project 3f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * 4f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 5f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * you may not use this file except in compliance with the License. 6f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * You may obtain a copy of the License at 7f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * 8f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 9f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * 10f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * Unless required by applicable law or agreed to in writing, software 11f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 12f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * See the License for the specific language governing permissions and 14f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * limitations under the License 15f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi */ 16f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi 17f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggipackage com.android.server.wm; 18f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi 1935e3f53a30588b79e0309fdbeef29a8c18eef65dJorim Jaggiimport static com.android.server.wm.TaskSnapshotPersister.*; 20f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 21f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 22f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi 23f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport android.app.ActivityManager.TaskSnapshot; 24f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport android.graphics.Bitmap; 25f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport android.graphics.Bitmap.Config; 26f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport android.graphics.BitmapFactory; 27f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport android.graphics.BitmapFactory.Options; 28f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport android.graphics.GraphicBuffer; 29f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport android.graphics.Rect; 30f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport android.util.Slog; 31f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi 32f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport com.android.server.wm.nano.WindowManagerProtos.TaskSnapshotProto; 33f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi 34f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport java.io.File; 35f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport java.io.IOException; 36f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiimport java.nio.file.Files; 37f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi 38f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi/** 39f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * Loads a persisted {@link TaskSnapshot} from disk. 40f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * <p> 41f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * Do not hold the window manager lock when accessing this class. 42f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * <p> 43f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * Test class: {@link TaskSnapshotPersisterLoaderTest} 44f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi */ 45f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggiclass TaskSnapshotLoader { 46f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi 47f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskSnapshotLoader" : TAG_WM; 48f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi 49f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi private final TaskSnapshotPersister mPersister; 50f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi 51f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi TaskSnapshotLoader(TaskSnapshotPersister persister) { 52f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi mPersister = persister; 53f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi } 54f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi 55f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi /** 56f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * Loads a task from the disk. 57f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * <p> 58f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * Do not hold the window manager lock when calling this method, as we directly read data from 59f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * disk here, which might be slow. 60f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * 61f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * @param taskId The id of the task to load. 62f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * @param userId The id of the user the task belonged to. 6335e3f53a30588b79e0309fdbeef29a8c18eef65dJorim Jaggi * @param reducedResolution Whether to load a reduced resolution version of the snapshot. 64f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi * @return The loaded {@link TaskSnapshot} or {@code null} if it couldn't be loaded. 65f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi */ 6635e3f53a30588b79e0309fdbeef29a8c18eef65dJorim Jaggi TaskSnapshot loadTask(int taskId, int userId, boolean reducedResolution) { 67f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi final File protoFile = mPersister.getProtoFile(taskId, userId); 6835e3f53a30588b79e0309fdbeef29a8c18eef65dJorim Jaggi final File bitmapFile = reducedResolution 6935e3f53a30588b79e0309fdbeef29a8c18eef65dJorim Jaggi ? mPersister.getReducedResolutionBitmapFile(taskId, userId) 7035e3f53a30588b79e0309fdbeef29a8c18eef65dJorim Jaggi : mPersister.getBitmapFile(taskId, userId); 713531dd064b9ff018fdf74aad5526948c7222acd4Matthew Ng if (bitmapFile == null || !protoFile.exists() || !bitmapFile.exists()) { 72f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi return null; 73f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi } 74f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi try { 75f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi final byte[] bytes = Files.readAllBytes(protoFile.toPath()); 76f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi final TaskSnapshotProto proto = TaskSnapshotProto.parseFrom(bytes); 77f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi final Options options = new Options(); 78f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi options.inPreferredConfig = Config.HARDWARE; 79f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi final Bitmap bitmap = BitmapFactory.decodeFile(bitmapFile.getPath(), options); 80f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi if (bitmap == null) { 81f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi Slog.w(TAG, "Failed to load bitmap: " + bitmapFile.getPath()); 82f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi return null; 83f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi } 84f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi final GraphicBuffer buffer = bitmap.createGraphicBufferHandle(); 85f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi if (buffer == null) { 86f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi Slog.w(TAG, "Failed to retrieve gralloc buffer for bitmap: " 87f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi + bitmapFile.getPath()); 88f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi return null; 89f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi } 90f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi return new TaskSnapshot(buffer, proto.orientation, 9135e3f53a30588b79e0309fdbeef29a8c18eef65dJorim Jaggi new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom), 92f3e412e5021c43491ed3ced61f02c2fd436e064eWinson Chung reducedResolution, reducedResolution ? REDUCED_SCALE : 1f, 93f3e412e5021c43491ed3ced61f02c2fd436e064eWinson Chung proto.isRealSnapshot); 94f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi } catch (IOException e) { 95f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi Slog.w(TAG, "Unable to load task snapshot data for taskId=" + taskId); 96f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi return null; 97f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi } 98f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi } 99f9084ecae2e0f042730ab32b9c94204a0e21bb2aJorim Jaggi} 100