• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.base;
6 
7 import android.content.res.AssetFileDescriptor;
8 import android.content.res.AssetManager;
9 import android.util.Log;
10 
11 import org.chromium.base.annotations.CalledByNative;
12 import org.chromium.base.annotations.JNINamespace;
13 
14 import java.io.IOException;
15 
16 /**
17  * A utility class to retrieve references to uncompressed assets insides the apk. A reference is
18  * defined as tuple (file descriptor, offset, size) enabling direct mapping without deflation.
19  * This can be used even within the renderer process, since it just dup's the apk's fd.
20  */
21 @JNINamespace("base::android")
22 public class ApkAssets {
23     private static final String LOGTAG = "ApkAssets";
24 
25     @CalledByNative
open(String fileName)26     public static long[] open(String fileName) {
27         AssetFileDescriptor afd = null;
28         try {
29             AssetManager manager = ContextUtils.getApplicationContext().getAssets();
30             afd = manager.openNonAssetFd(fileName);
31             return new long[] {afd.getParcelFileDescriptor().detachFd(), afd.getStartOffset(),
32                     afd.getLength()};
33         } catch (IOException e) {
34             // As a general rule there's no point logging here because the caller should handle
35             // receiving an fd of -1 sensibly, and the log message is either mirrored later, or
36             // unwanted (in the case where a missing file is expected), or wanted but will be
37             // ignored, as most non-fatal logs are.
38             // It makes sense to log here when the file exists, but is unable to be opened as an fd
39             // because (for example) it is unexpectedly compressed in an apk. In that case, the log
40             // message might save someone some time working out what has gone wrong.
41             // For that reason, we only suppress the message when the exception message doesn't look
42             // informative (Android framework passes the filename as the message on actual file not
43             // found, and the empty string also wouldn't give any useful information for debugging).
44             if (!e.getMessage().equals("") && !e.getMessage().equals(fileName)) {
45                 Log.e(LOGTAG, "Error while loading asset " + fileName + ": " + e);
46             }
47             return new long[] {-1, -1, -1};
48         } finally {
49             try {
50                 if (afd != null) {
51                     afd.close();
52                 }
53             } catch (IOException e2) {
54                 Log.e(LOGTAG, "Unable to close AssetFileDescriptor", e2);
55             }
56         }
57     }
58 }
59