1 /*
2  * Copyright (C) 2022 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 android.annotation.NonNull;
20 import android.window.TaskSnapshot;
21 
22 import java.io.File;
23 
24 class BaseAppSnapshotPersister {
25     static final String LOW_RES_FILE_POSTFIX = "_reduced";
26     static final String PROTO_EXTENSION = ".proto";
27     static final String BITMAP_EXTENSION = ".jpg";
28 
29     // Shared with SnapshotPersistQueue
30     protected final Object mLock;
31     protected final SnapshotPersistQueue mSnapshotPersistQueue;
32     protected final PersistInfoProvider mPersistInfoProvider;
33 
BaseAppSnapshotPersister(SnapshotPersistQueue persistQueue, PersistInfoProvider persistInfoProvider)34     BaseAppSnapshotPersister(SnapshotPersistQueue persistQueue,
35             PersistInfoProvider persistInfoProvider) {
36         mSnapshotPersistQueue = persistQueue;
37         mPersistInfoProvider = persistInfoProvider;
38         mLock = persistQueue.getLock();
39     }
40 
41     /**
42      * Persists a snapshot of a task to disk.
43      *
44      * @param id The id of the object that needs to be persisted.
45      * @param userId The id of the user this tasks belongs to.
46      * @param snapshot The snapshot to persist.
47      */
persistSnapshot(int id, int userId, TaskSnapshot snapshot)48     void persistSnapshot(int id, int userId, TaskSnapshot snapshot) {
49         synchronized (mLock) {
50             mSnapshotPersistQueue.sendToQueueLocked(mSnapshotPersistQueue
51                     .createStoreWriteQueueItem(id, userId, snapshot, mPersistInfoProvider));
52         }
53     }
54 
55     /**
56      * Called to remove the persisted file
57      *
58      * @param id The id of task that has been removed.
59      * @param userId The id of the user the task belonged to.
60      */
removeSnapshot(int id, int userId)61     void removeSnapshot(int id, int userId) {
62         synchronized (mLock) {
63             mSnapshotPersistQueue.sendToQueueLocked(mSnapshotPersistQueue
64                     .createDeleteWriteQueueItem(id, userId, mPersistInfoProvider));
65         }
66     }
67 
68     interface DirectoryResolver {
getSystemDirectoryForUser(int userId)69         File getSystemDirectoryForUser(int userId);
70     }
71 
72     /**
73      * Persist information provider, the snapshot persister and loader can know where the file is,
74      * and the scale of a snapshot, etc.
75      */
76     static class PersistInfoProvider {
77         protected final DirectoryResolver mDirectoryResolver;
78         private final String mDirName;
79         private final boolean mEnableLowResSnapshots;
80         private final float mLowResScaleFactor;
81         private final boolean mUse16BitFormat;
82 
PersistInfoProvider(DirectoryResolver directoryResolver, String dirName, boolean enableLowResSnapshots, float lowResScaleFactor, boolean use16BitFormat)83         PersistInfoProvider(DirectoryResolver directoryResolver, String dirName,
84                 boolean enableLowResSnapshots, float lowResScaleFactor, boolean use16BitFormat) {
85             mDirectoryResolver = directoryResolver;
86             mDirName = dirName;
87             mEnableLowResSnapshots = enableLowResSnapshots;
88             mLowResScaleFactor = lowResScaleFactor;
89             mUse16BitFormat = use16BitFormat;
90         }
91 
92         @NonNull
getDirectory(int userId)93         File getDirectory(int userId) {
94             return new File(mDirectoryResolver.getSystemDirectoryForUser(userId), mDirName);
95         }
96 
97         /**
98          * Return if task snapshots are stored in 16 bit pixel format.
99          *
100          * @return true if task snapshots are stored in 16 bit pixel format.
101          */
use16BitFormat()102         boolean use16BitFormat() {
103             return mUse16BitFormat;
104         }
105 
createDirectory(int userId)106         boolean createDirectory(int userId) {
107             final File dir = getDirectory(userId);
108             return dir.exists() || dir.mkdir();
109         }
110 
getProtoFile(int index, int userId)111         File getProtoFile(int index, int userId) {
112             return new File(getDirectory(userId), index + PROTO_EXTENSION);
113         }
114 
getLowResolutionBitmapFile(int index, int userId)115         File getLowResolutionBitmapFile(int index, int userId) {
116             return new File(getDirectory(userId), index + LOW_RES_FILE_POSTFIX + BITMAP_EXTENSION);
117         }
118 
getHighResolutionBitmapFile(int index, int userId)119         File getHighResolutionBitmapFile(int index, int userId) {
120             return new File(getDirectory(userId), index + BITMAP_EXTENSION);
121         }
122 
enableLowResSnapshots()123         boolean enableLowResSnapshots() {
124             return mEnableLowResSnapshots;
125         }
126 
lowResScaleFactor()127         float lowResScaleFactor() {
128             return mLowResScaleFactor;
129         }
130     }
131 }
132