• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <nativehelper/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 
AAssetDirAAssetDir42     explicit AAssetDir(AssetDir* dir) : mAssetDir(dir), mCurFileIndex(0) { }
~AAssetDirAAssetDir43     ~AAssetDir() { delete mAssetDir; }
44 };
45 
46 
47 // -----
48 struct AAsset {
49     Asset* mAsset;
50 
AAssetAAsset51     explicit AAsset(Asset* asset) : mAsset(asset) { }
~AAssetAAsset52     ~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  */
AAssetManager_fromJava(JNIEnv * env,jobject assetManager)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 
AAssetManager_open(AAssetManager * amgr,const char * filename,int mode)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 
AAssetManager_openDir(AAssetManager * amgr,const char * dirName)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 
AAssetDir_getNextFileName(AAssetDir * assetDir)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 
AAssetDir_rewind(AAssetDir * assetDir)151 void AAssetDir_rewind(AAssetDir* assetDir)
152 {
153     assetDir->mCurFileIndex = 0;
154 }
155 
AAssetDir_getFileName(AAssetDir * assetDir,int index)156 const char* AAssetDir_getFileName(AAssetDir* assetDir, int index)
157 {
158     assetDir->mCachedFileName = assetDir->mAssetDir->getFileName(index);
159     return assetDir->mCachedFileName.string();
160 }
161 
AAssetDir_close(AAssetDir * assetDir)162 void AAssetDir_close(AAssetDir* assetDir)
163 {
164     delete assetDir;
165 }
166 
167 /**
168  * Asset functionality
169  */
170 
AAsset_read(AAsset * asset,void * buf,size_t count)171 int AAsset_read(AAsset* asset, void* buf, size_t count)
172 {
173     return asset->mAsset->read(buf, (size_t)count);
174 }
175 
AAsset_seek(AAsset * asset,off_t offset,int whence)176 off_t AAsset_seek(AAsset* asset, off_t offset, int whence)
177 {
178     return asset->mAsset->seek(offset, whence);
179 }
180 
AAsset_seek64(AAsset * asset,off64_t offset,int whence)181 off64_t AAsset_seek64(AAsset* asset, off64_t offset, int whence)
182 {
183     return asset->mAsset->seek(offset, whence);
184 }
185 
AAsset_close(AAsset * asset)186 void AAsset_close(AAsset* asset)
187 {
188     asset->mAsset->close();
189     delete asset;
190 }
191 
AAsset_getBuffer(AAsset * asset)192 const void* AAsset_getBuffer(AAsset* asset)
193 {
194     return asset->mAsset->getBuffer(false);
195 }
196 
AAsset_getLength(AAsset * asset)197 off_t AAsset_getLength(AAsset* asset)
198 {
199     return asset->mAsset->getLength();
200 }
201 
AAsset_getLength64(AAsset * asset)202 off64_t AAsset_getLength64(AAsset* asset)
203 {
204     return asset->mAsset->getLength();
205 }
206 
AAsset_getRemainingLength(AAsset * asset)207 off_t AAsset_getRemainingLength(AAsset* asset)
208 {
209     return asset->mAsset->getRemainingLength();
210 }
211 
AAsset_getRemainingLength64(AAsset * asset)212 off64_t AAsset_getRemainingLength64(AAsset* asset)
213 {
214     return asset->mAsset->getRemainingLength();
215 }
216 
AAsset_openFileDescriptor(AAsset * asset,off_t * outStart,off_t * outLength)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 
AAsset_openFileDescriptor64(AAsset * asset,off64_t * outStart,off64_t * outLength)228 int AAsset_openFileDescriptor64(AAsset* asset, off64_t* outStart, off64_t* outLength)
229 {
230     return asset->mAsset->openFileDescriptor(outStart, outLength);
231 }
232 
AAsset_isAllocated(AAsset * asset)233 int AAsset_isAllocated(AAsset* asset)
234 {
235     return asset->mAsset->isAllocated() ? 1 : 0;
236 }
237