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