• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
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 package com.google.android.libraries.mobiledatadownload.file.openers;
17 
18 import android.net.Uri;
19 import android.util.Pair;
20 import com.google.android.libraries.mobiledatadownload.file.OpenContext;
21 import com.google.android.libraries.mobiledatadownload.file.Opener;
22 import java.io.Closeable;
23 import java.io.IOException;
24 
25 /**
26  * An opener that produces a file descriptor URI (like "fd:123"). This is useful for opening a file
27  * in Java and passing a handle to it down to C++.
28  *
29  * <p>Transforms are not applied in the Java code and are retained in the returned URI so they can
30  * be applied in native code.
31  *
32  * <p>The caller is responsible for closing the file descriptor. The native code is expected to dup
33  * the descriptor if it needs to hold it, so they can both call close independently.
34  *
35  * <p>Usage: <code>
36  * try (CloseableUri fdUri = storage.open(uri, NativeReadOpener.create())) {
37  *   // Use URI in native code
38  * }
39  * </code>
40  */
41 public final class NativeReadOpener implements Opener<CloseableUri> {
NativeReadOpener()42   private NativeReadOpener() {}
43 
create()44   public static NativeReadOpener create() {
45     return new NativeReadOpener();
46   }
47 
48   @Override
open(OpenContext openContext)49   public CloseableUri open(OpenContext openContext) throws IOException {
50     Pair<Uri, Closeable> result = openContext.backend().openForNativeRead(openContext.encodedUri());
51     Uri uriWithFragment =
52         result
53             .first
54             .buildUpon()
55             .encodedFragment(openContext.originalUri().getEncodedFragment())
56             .build();
57     return new CloseableUri() {
58       @Override
59       public Uri uri() {
60         return uriWithFragment;
61       }
62 
63       @Override
64       public void close() throws IOException {
65         result.second.close();
66       }
67     };
68   }
69 }
70