Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright (C) 2010 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 #define LOG_TAG "NAsset"
     18 #include <utils/Log.h>
     19 
     20 #include <android/asset_manager_jni.h>
     21 #include <androidfw/Asset.h>
     22 #include <androidfw/AssetDir.h>
     23 #include <androidfw/AssetManager.h>
     24 #include <utils/threads.h>
     25 
     26 #include "jni.h"
     27 #include "JNIHelp.h"
     28 
     29 using namespace android;
     30 
     31 // -------------------- Backing implementation of the public API --------------------
     32 
     33 // AAssetManager is actually a secret typedef for an empty base class of AssetManager,
     34 // but AAssetDir and AAsset are actual wrappers for isolation.
     35 
     36 // -----
     37 struct AAssetDir {
     38     AssetDir* mAssetDir;
     39     size_t mCurFileIndex;
     40     String8 mCachedFileName;
     41 
     42     AAssetDir(AssetDir* dir) : mAssetDir(dir), mCurFileIndex(0) { }
     43     ~AAssetDir() { delete mAssetDir; }
     44 };
     45 
     46 
     47 // -----
     48 struct AAsset {
     49     Asset* mAsset;
     50 
     51     AAsset(Asset* asset) : mAsset(asset) { }
     52     ~AAsset() { delete mAsset; }
     53 };
     54 
     55 // -------------------- Public native C API --------------------
     56 
     57 /**
     58  * Supporting information
     59  */
     60 
     61 static struct assetmanager_offsets_t
     62 {
     63     jfieldID mObject;
     64 } gAssetManagerOffsets;
     65 
     66 static volatile bool gJNIConfigured = false;
     67 static Mutex gMutex;
     68 
     69 /**
     70  * Asset Manager functionality
     71  */
     72 AAssetManager* AAssetManager_fromJava(JNIEnv* env, jobject assetManager)
     73 {
     74     {
     75         Mutex::Autolock _l(gMutex);
     76 
     77         if (gJNIConfigured == false) {
     78             jclass amClass = env->FindClass("android/content/res/AssetManager");
     79             gAssetManagerOffsets.mObject = env->GetFieldID(amClass, "mObject", "J");
     80             gJNIConfigured = true;
     81         }
     82     }
     83 
     84     return (AAssetManager*) env->GetLongField(assetManager, gAssetManagerOffsets.mObject);
     85 }
     86 
     87 AAsset* AAssetManager_open(AAssetManager* amgr, const char* filename, int mode)
     88 {
     89     Asset::AccessMode amMode;
     90     switch (mode) {
     91     case AASSET_MODE_UNKNOWN:
     92         amMode = Asset::ACCESS_UNKNOWN;
     93         break;
     94     case AASSET_MODE_RANDOM:
     95         amMode = Asset::ACCESS_RANDOM;
     96         break;
     97     case AASSET_MODE_STREAMING:
     98         amMode = Asset::ACCESS_STREAMING;
     99         break;
    100     case AASSET_MODE_BUFFER:
    101         amMode = Asset::ACCESS_BUFFER;
    102         break;
    103     default:
    104         return NULL;
    105     }
    106 
    107     AssetManager* mgr = static_cast<AssetManager*>(amgr);
    108     Asset* asset = mgr->open(filename, amMode);
    109     if (asset == NULL) {
    110         return NULL;
    111     }
    112 
    113     return new AAsset(asset);
    114 }
    115 
    116 AAssetDir* AAssetManager_openDir(AAssetManager* amgr, const char* dirName)
    117 {
    118     AssetManager* mgr = static_cast<AssetManager*>(amgr);
    119     return new AAssetDir(mgr->openDir(dirName));
    120 }
    121 
    122 /**
    123  * AssetDir functionality
    124  */
    125 
    126 const char* AAssetDir_getNextFileName(AAssetDir* assetDir)
    127 {
    128     const char* returnName = NULL;
    129     size_t index = assetDir->mCurFileIndex;
    130     const size_t max = assetDir->mAssetDir->getFileCount();
    131 
    132     // Find the next regular file; explicitly don't report directories even if the
    133     // underlying implementation changes to report them.  At that point we can add
    134     // a more general iterator to this native interface set if appropriate.
    135     while ((index < max) && (assetDir->mAssetDir->getFileType(index) != kFileTypeRegular)) {
    136         index++;
    137     }
    138 
    139     // still in bounds? then the one at 'index' is the next to be reported; generate
    140     // the string to return and advance the iterator for next time.
    141     if (index < max) {
    142         assetDir->mCachedFileName = assetDir->mAssetDir->getFileName(index);
    143         returnName = assetDir->mCachedFileName.string();
    144         index++;
    145     }
    146 
    147     assetDir->mCurFileIndex = index;
    148     return returnName;
    149 }
    150 
    151 void AAssetDir_rewind(AAssetDir* assetDir)
    152 {
    153     assetDir->mCurFileIndex = 0;
    154 }
    155 
    156 const char* AAssetDir_getFileName(AAssetDir* assetDir, int index)
    157 {
    158     assetDir->mCachedFileName = assetDir->mAssetDir->getFileName(index);
    159     return assetDir->mCachedFileName.string();
    160 }
    161 
    162 void AAssetDir_close(AAssetDir* assetDir)
    163 {
    164     delete assetDir;
    165 }
    166 
    167 /**
    168  * Asset functionality
    169  */
    170 
    171 int AAsset_read(AAsset* asset, void* buf, size_t count)
    172 {
    173     return asset->mAsset->read(buf, (size_t)count);
    174 }
    175 
    176 off_t AAsset_seek(AAsset* asset, off_t offset, int whence)
    177 {
    178     return asset->mAsset->seek(offset, whence);
    179 }
    180 
    181 off64_t AAsset_seek64(AAsset* asset, off64_t offset, int whence)
    182 {
    183     return asset->mAsset->seek(offset, whence);
    184 }
    185 
    186 void AAsset_close(AAsset* asset)
    187 {
    188     asset->mAsset->close();
    189     delete asset;
    190 }
    191 
    192 const void* AAsset_getBuffer(AAsset* asset)
    193 {
    194     return asset->mAsset->getBuffer(false);
    195 }
    196 
    197 off_t AAsset_getLength(AAsset* asset)
    198 {
    199     return asset->mAsset->getLength();
    200 }
    201 
    202 off64_t AAsset_getLength64(AAsset* asset)
    203 {
    204     return asset->mAsset->getLength();
    205 }
    206 
    207 off_t AAsset_getRemainingLength(AAsset* asset)
    208 {
    209     return asset->mAsset->getRemainingLength();
    210 }
    211 
    212 off64_t AAsset_getRemainingLength64(AAsset* asset)
    213 {
    214     return asset->mAsset->getRemainingLength();
    215 }
    216 
    217 int AAsset_openFileDescriptor(AAsset* asset, off_t* outStart, off_t* outLength)
    218 {
    219     off64_t outStart64, outLength64;
    220 
    221     int ret = asset->mAsset->openFileDescriptor(&outStart64, &outLength64);
    222 
    223     *outStart = off_t(outStart64);
    224     *outLength = off_t(outLength64);
    225     return ret;
    226 }
    227 
    228 int AAsset_openFileDescriptor64(AAsset* asset, off64_t* outStart, off64_t* outLength)
    229 {
    230     return asset->mAsset->openFileDescriptor(outStart, outLength);
    231 }
    232 
    233 int AAsset_isAllocated(AAsset* asset)
    234 {
    235     return asset->mAsset->isAllocated() ? 1 : 0;
    236 }
    237