1 /*
2  * Copyright 2021 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 androidx.camera.video;
18 
19 import android.os.ParcelFileDescriptor;
20 
21 import androidx.core.util.Preconditions;
22 
23 import com.google.auto.value.AutoValue;
24 
25 import org.jspecify.annotations.NonNull;
26 import org.jspecify.annotations.Nullable;
27 
28 /**
29  * A class providing options for storing the result to a given file descriptor.
30  *
31  * <p>The file descriptor must be seekable and writable. The caller is responsible for closing
32  * the file descriptor, which can be safely closed after the recording starts. That is, after
33  * {@link PendingRecording#start(java.util.concurrent.Executor, androidx.core.util.Consumer)} returns. Application should not use the file referenced by
34  * this file descriptor until the recording is complete.
35  *
36  * <p>To use a {@link java.io.File} as an output destination instead of a file descriptor, use
37  * {@link FileOutputOptions}.
38  */
39 public final class FileDescriptorOutputOptions extends OutputOptions {
40 
41     private final FileDescriptorOutputOptionsInternal mFileDescriptorOutputOptionsInternal;
42 
FileDescriptorOutputOptions( @onNull FileDescriptorOutputOptionsInternal fileDescriptorOutputOptionsInternal)43     FileDescriptorOutputOptions(
44             @NonNull FileDescriptorOutputOptionsInternal fileDescriptorOutputOptionsInternal) {
45         super(fileDescriptorOutputOptionsInternal);
46         mFileDescriptorOutputOptionsInternal = fileDescriptorOutputOptionsInternal;
47     }
48 
49     /**
50      * Gets the file descriptor instance.
51      *
52      * @return the file descriptor used as the output destination.
53      */
getParcelFileDescriptor()54     public @NonNull ParcelFileDescriptor getParcelFileDescriptor() {
55         return mFileDescriptorOutputOptionsInternal.getParcelFileDescriptor();
56     }
57 
58     @Override
toString()59     public @NonNull String toString() {
60         // Don't use Class.getSimpleName(), class name will be changed by proguard obfuscation.
61         return mFileDescriptorOutputOptionsInternal.toString().replaceFirst(
62                 "FileDescriptorOutputOptionsInternal", "FileDescriptorOutputOptions");
63     }
64 
65     @Override
equals(@ullable Object o)66     public boolean equals(@Nullable Object o) {
67         if (this == o) {
68             return true;
69         }
70         if (!(o instanceof FileDescriptorOutputOptions)) {
71             return false;
72         }
73         return mFileDescriptorOutputOptionsInternal.equals(
74                 ((FileDescriptorOutputOptions) o).mFileDescriptorOutputOptionsInternal);
75     }
76 
77     @Override
hashCode()78     public int hashCode() {
79         return mFileDescriptorOutputOptionsInternal.hashCode();
80     }
81 
82     /** The builder of the {@link FileDescriptorOutputOptions} object. */
83     public static final class Builder extends
84             OutputOptions.Builder<FileDescriptorOutputOptions, Builder> {
85 
86         private final FileDescriptorOutputOptionsInternal.Builder mInternalBuilder;
87 
88         /**
89          * Creates a builder of the {@link FileDescriptorOutputOptions} with a file descriptor.
90          *
91          * @param fileDescriptor the file descriptor to use as the output destination.
92          */
Builder(@onNull ParcelFileDescriptor fileDescriptor)93         public Builder(@NonNull ParcelFileDescriptor fileDescriptor) {
94             super(new AutoValue_FileDescriptorOutputOptions_FileDescriptorOutputOptionsInternal
95                     .Builder());
96             Preconditions.checkNotNull(fileDescriptor, "File descriptor can't be null.");
97             mInternalBuilder = (FileDescriptorOutputOptionsInternal.Builder) mRootInternalBuilder;
98             mInternalBuilder.setParcelFileDescriptor(fileDescriptor);
99         }
100 
101         /** Builds the {@link FileDescriptorOutputOptions} instance. */
102         @Override
build()103         public @NonNull FileDescriptorOutputOptions build() {
104             return new FileDescriptorOutputOptions(mInternalBuilder.build());
105         }
106     }
107 
108     @AutoValue
109     abstract static class FileDescriptorOutputOptionsInternal extends OutputOptionsInternal {
getParcelFileDescriptor()110         abstract @NonNull ParcelFileDescriptor getParcelFileDescriptor();
111 
112         @SuppressWarnings("NullableProblems") // Nullable problem in AutoValue generated class
113         @AutoValue.Builder
114         abstract static class Builder extends OutputOptionsInternal.Builder<Builder> {
setParcelFileDescriptor( @onNull ParcelFileDescriptor parcelFileDescriptor)115             abstract @NonNull Builder setParcelFileDescriptor(
116                     @NonNull ParcelFileDescriptor parcelFileDescriptor);
117             @Override
build()118             abstract @NonNull FileDescriptorOutputOptionsInternal build();
119         }
120     }
121 }
122