resources/src/main/java/org/robolectric/res/android/CppAssetManager.java
public Asset open(final String fileName, AccessMode mode) {
    synchronized (mLock) {
      LOG_FATAL_IF(mAssetPaths.isEmpty(), "No assets added to AssetManager");

      String8 assetName = new String8(kAssetsRoot);
      assetName.appendPath(fileName);
      /*
       * For each top-level asset path, search for the asset.
       */
      int i = mAssetPaths.size();
      while (i > 0) {
        i--;
        ALOGV("Looking for asset '%s' in '%s'\n",
            assetName.string(), mAssetPaths.get(i).path.string());
        Asset pAsset = openNonAssetInPathLocked(assetName.string(), mode,
            mAssetPaths.get(i));
        if (pAsset != null) {
          return Objects.equals(pAsset, kExcludedAsset) ? null : pAsset;
        }
      }

      return null;
    }
  }
public Asset open(final String fileName, AccessMode mode) {
    synchronized (mLock) {
      LOG_FATAL_IF(mAssetPaths.isEmpty(), "No assets added to AssetManager");

      String8 assetName = new String8(kAssetsRoot);
      assetName.appendPath(fileName);
      /*
       * For each top-level asset path, search for the asset.
       */
      int i = mAssetPaths.size();
      while (i > 0) {
        i--;
        ALOGV("Looking for asset '%s' in '%s'\n",
            assetName.string(), mAssetPaths.get(i).path.string());
        Asset pAsset = openNonAssetInPathLocked(assetName.string(), mode,
            mAssetPaths.get(i));
        if (pAsset != null) {
          return Objects.equals(pAsset, kExcludedAsset) ? null : pAsset;
        }
      }

      return null;
    }
  }
/*
Open an asset.

The data could be in any asset path. Each asset path could be:
- A directory on disk.
- A Zip archive, uncompressed or compressed.

If the file is in a directory, it could have a .gz suffix, meaning it is compressed.

We should probably reject requests for "illegal" filenames, e.g. those
with illegal characters or "../" backward relative paths.