Home | History | Annotate | Download | only in wm
      1 /*
      2  * Copyright (C) 2017 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.server.wm;
     18 
     19 import static com.android.server.wm.TaskSnapshotPersister.*;
     20 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
     21 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
     22 
     23 import android.app.ActivityManager.TaskSnapshot;
     24 import android.graphics.Bitmap;
     25 import android.graphics.Bitmap.Config;
     26 import android.graphics.BitmapFactory;
     27 import android.graphics.BitmapFactory.Options;
     28 import android.graphics.GraphicBuffer;
     29 import android.graphics.Rect;
     30 import android.util.Slog;
     31 
     32 import com.android.server.wm.nano.WindowManagerProtos.TaskSnapshotProto;
     33 
     34 import java.io.File;
     35 import java.io.IOException;
     36 import java.nio.file.Files;
     37 
     38 /**
     39  * Loads a persisted {@link TaskSnapshot} from disk.
     40  * <p>
     41  * Do not hold the window manager lock when accessing this class.
     42  * <p>
     43  * Test class: {@link TaskSnapshotPersisterLoaderTest}
     44  */
     45 class TaskSnapshotLoader {
     46 
     47     private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskSnapshotLoader" : TAG_WM;
     48 
     49     private final TaskSnapshotPersister mPersister;
     50 
     51     TaskSnapshotLoader(TaskSnapshotPersister persister) {
     52         mPersister = persister;
     53     }
     54 
     55     /**
     56      * Loads a task from the disk.
     57      * <p>
     58      * Do not hold the window manager lock when calling this method, as we directly read data from
     59      * disk here, which might be slow.
     60      *
     61      * @param taskId The id of the task to load.
     62      * @param userId The id of the user the task belonged to.
     63      * @param reducedResolution Whether to load a reduced resolution version of the snapshot.
     64      * @return The loaded {@link TaskSnapshot} or {@code null} if it couldn't be loaded.
     65      */
     66     TaskSnapshot loadTask(int taskId, int userId, boolean reducedResolution) {
     67         final File protoFile = mPersister.getProtoFile(taskId, userId);
     68         final File bitmapFile = reducedResolution
     69                 ? mPersister.getReducedResolutionBitmapFile(taskId, userId)
     70                 : mPersister.getBitmapFile(taskId, userId);
     71         if (!protoFile.exists() || !bitmapFile.exists()) {
     72             return null;
     73         }
     74         try {
     75             final byte[] bytes = Files.readAllBytes(protoFile.toPath());
     76             final TaskSnapshotProto proto = TaskSnapshotProto.parseFrom(bytes);
     77             final Options options = new Options();
     78             options.inPreferredConfig = Config.HARDWARE;
     79             final Bitmap bitmap = BitmapFactory.decodeFile(bitmapFile.getPath(), options);
     80             if (bitmap == null) {
     81                 Slog.w(TAG, "Failed to load bitmap: " + bitmapFile.getPath());
     82                 return null;
     83             }
     84             final GraphicBuffer buffer = bitmap.createGraphicBufferHandle();
     85             if (buffer == null) {
     86                 Slog.w(TAG, "Failed to retrieve gralloc buffer for bitmap: "
     87                         + bitmapFile.getPath());
     88                 return null;
     89             }
     90             return new TaskSnapshot(buffer, proto.orientation,
     91                     new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
     92                     reducedResolution, reducedResolution ? REDUCED_SCALE : 1f);
     93         } catch (IOException e) {
     94             Slog.w(TAG, "Unable to load task snapshot data for taskId=" + taskId);
     95             return null;
     96         }
     97     }
     98 }
     99