• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 android.system.virtualmachine;
18 
19 import static java.util.Objects.requireNonNull;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.SystemApi;
24 import android.os.Parcel;
25 import android.os.ParcelFileDescriptor;
26 import android.os.Parcelable;
27 
28 import java.io.IOException;
29 
30 /**
31  * A VM descriptor that captures the state of a Virtual Machine.
32  *
33  * <p>You can capture the current state of VM by creating an instance of this class with {@link
34  * VirtualMachine#toDescriptor}, optionally pass it to another App, and then build an identical VM
35  * with the descriptor received.
36  *
37  * @hide
38  */
39 @SystemApi
40 public final class VirtualMachineDescriptor implements Parcelable, AutoCloseable {
41     private volatile boolean mClosed = false;
42     @NonNull private final ParcelFileDescriptor mConfigFd;
43     @NonNull private final ParcelFileDescriptor mInstanceImgFd;
44     // File descriptor of the image backing the encrypted storage - Will be null if encrypted
45     // storage is not enabled. */
46     @Nullable private final ParcelFileDescriptor mEncryptedStoreFd;
47 
48     @Override
describeContents()49     public int describeContents() {
50         return CONTENTS_FILE_DESCRIPTOR;
51     }
52 
53     @Override
writeToParcel(@onNull Parcel out, int flags)54     public void writeToParcel(@NonNull Parcel out, int flags) {
55         checkNotClosed();
56         out.writeParcelable(mConfigFd, flags);
57         out.writeParcelable(mInstanceImgFd, flags);
58         out.writeParcelable(mEncryptedStoreFd, flags);
59     }
60 
61     @NonNull
62     public static final Parcelable.Creator<VirtualMachineDescriptor> CREATOR =
63             new Parcelable.Creator<>() {
64                 public VirtualMachineDescriptor createFromParcel(Parcel in) {
65                     return new VirtualMachineDescriptor(in);
66                 }
67 
68                 public VirtualMachineDescriptor[] newArray(int size) {
69                     return new VirtualMachineDescriptor[size];
70                 }
71             };
72 
73     /**
74      * @return File descriptor of the VM configuration file config.xml.
75      */
76     @NonNull
getConfigFd()77     ParcelFileDescriptor getConfigFd() {
78         checkNotClosed();
79         return mConfigFd;
80     }
81 
82     /**
83      * @return File descriptor of the instance.img of the VM.
84      */
85     @NonNull
getInstanceImgFd()86     ParcelFileDescriptor getInstanceImgFd() {
87         checkNotClosed();
88         return mInstanceImgFd;
89     }
90 
91     /**
92      * @return File descriptor of image backing the encrypted storage.
93      *     <p>This method will return null if encrypted storage is not enabled.
94      */
95     @Nullable
getEncryptedStoreFd()96     ParcelFileDescriptor getEncryptedStoreFd() {
97         checkNotClosed();
98         return mEncryptedStoreFd;
99     }
100 
VirtualMachineDescriptor( @onNull ParcelFileDescriptor configFd, @NonNull ParcelFileDescriptor instanceImgFd, @Nullable ParcelFileDescriptor encryptedStoreFd)101     VirtualMachineDescriptor(
102             @NonNull ParcelFileDescriptor configFd,
103             @NonNull ParcelFileDescriptor instanceImgFd,
104             @Nullable ParcelFileDescriptor encryptedStoreFd) {
105         mConfigFd = requireNonNull(configFd);
106         mInstanceImgFd = requireNonNull(instanceImgFd);
107         mEncryptedStoreFd = encryptedStoreFd;
108     }
109 
VirtualMachineDescriptor(Parcel in)110     private VirtualMachineDescriptor(Parcel in) {
111         mConfigFd = requireNonNull(readParcelFileDescriptor(in));
112         mInstanceImgFd = requireNonNull(readParcelFileDescriptor(in));
113         mEncryptedStoreFd = readParcelFileDescriptor(in);
114     }
115 
readParcelFileDescriptor(Parcel in)116     private ParcelFileDescriptor readParcelFileDescriptor(Parcel in) {
117         return in.readParcelable(
118                 ParcelFileDescriptor.class.getClassLoader(), ParcelFileDescriptor.class);
119     }
120 
121     /**
122      * Release any resources held by this descriptor. Calling {@code close} on an already-closed
123      * descriptor has no effect.
124      */
125     @Override
close()126     public void close() {
127         mClosed = true;
128         // Let the compiler do the work: close everything, throw if any of them fail, skipping null.
129         try (mConfigFd;
130                 mInstanceImgFd;
131                 mEncryptedStoreFd) {
132         } catch (IOException ignored) {
133             // PFD already swallows exceptions from closing the fd. There's no reason to propagate
134             // this to the caller.
135         }
136     }
137 
checkNotClosed()138     private void checkNotClosed() {
139         if (mClosed) {
140             throw new IllegalStateException("Descriptor has been closed");
141         }
142     }
143 }
144