storage_manager.cpp revision 6215d3ff4b5dfa52a5d8b9a42e343051f31066a5
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 "NStorage" 18 19#include <android/storage_manager.h> 20#include <storage/IMountService.h> 21 22#include <binder/Binder.h> 23#include <binder/IServiceManager.h> 24#include <utils/Atomic.h> 25#include <utils/Log.h> 26#include <utils/RefBase.h> 27#include <utils/String8.h> 28#include <utils/String16.h> 29#include <utils/Vector.h> 30#include <utils/threads.h> 31 32 33using namespace android; 34 35struct ObbActionListener : public BnObbActionListener { 36private: 37 sp<AStorageManager> mStorageManager; 38 39public: 40 ObbActionListener(AStorageManager* mgr) : 41 mStorageManager(mgr) 42 {} 43 44 virtual void onObbResult(const android::String16& filename, const int32_t nonce, 45 const int32_t state); 46}; 47 48class ObbCallback { 49public: 50 ObbCallback(int32_t _nonce, AStorageManager_obbCallbackFunc _cb, void* _data) 51 : nonce(_nonce) 52 , cb(_cb) 53 , data(_data) 54 {} 55 56 int32_t nonce; 57 AStorageManager_obbCallbackFunc cb; 58 void* data; 59}; 60 61struct AStorageManager : public RefBase { 62protected: 63 Mutex mCallbackLock; 64 Vector<ObbCallback*> mCallbacks; 65 volatile int32_t mNextNonce; 66 sp<ObbActionListener> mObbActionListener; 67 sp<IMountService> mMountService; 68 69 int32_t getNextNonce() { 70 return android_atomic_inc(&mNextNonce); 71 } 72 73 ObbCallback* registerObbCallback(AStorageManager_obbCallbackFunc func, void* data) { 74 ObbCallback* cb = new ObbCallback(getNextNonce(), func, data); 75 { 76 AutoMutex _l(mCallbackLock); 77 mCallbacks.push(cb); 78 } 79 return cb; 80 } 81 82public: 83 AStorageManager() 84 { 85 } 86 87 bool initialize() { 88 sp<IServiceManager> sm = defaultServiceManager(); 89 if (sm == NULL) { 90 LOGE("Couldn't get default ServiceManager\n"); 91 return false; 92 } 93 94 mMountService = interface_cast<IMountService>(sm->getService(String16("mount"))); 95 if (mMountService == NULL) { 96 LOGE("Couldn't get connection to MountService\n"); 97 return false; 98 } 99 100 mObbActionListener = new ObbActionListener(this); 101 102 return true; 103 } 104 105 void fireCallback(const char* filename, const int32_t nonce, const int32_t state) { 106 ObbCallback* target = NULL; 107 { 108 AutoMutex _l(mCallbackLock); 109 int N = mCallbacks.size(); 110 for (int i = 0; i < N; i++) { 111 ObbCallback* cb = mCallbacks.editItemAt(i); 112 if (cb->nonce == nonce) { 113 target = cb; 114 mCallbacks.removeAt(i); 115 break; 116 } 117 } 118 } 119 120 if (target != NULL) { 121 target->cb(filename, state, target->data); 122 delete target; 123 } else { 124 ALOGI("Didn't find the callback handler for: %s\n", filename); 125 } 126 } 127 128 void mountObb(const char* filename, const char* key, AStorageManager_obbCallbackFunc func, void* data) { 129 ObbCallback* cb = registerObbCallback(func, data); 130 String16 filename16(filename); 131 String16 key16(key); 132 mMountService->mountObb(filename16, key16, mObbActionListener, cb->nonce); 133 } 134 135 void unmountObb(const char* filename, const bool force, AStorageManager_obbCallbackFunc func, void* data) { 136 ObbCallback* cb = registerObbCallback(func, data); 137 String16 filename16(filename); 138 mMountService->unmountObb(filename16, force, mObbActionListener, cb->nonce); 139 } 140 141 int isObbMounted(const char* filename) { 142 String16 filename16(filename); 143 return mMountService->isObbMounted(filename16); 144 } 145 146 const char* getMountedObbPath(const char* filename) { 147 String16 filename16(filename); 148 String16 path16; 149 if (mMountService->getMountedObbPath(filename16, path16)) { 150 return String8(path16).string(); 151 } else { 152 return NULL; 153 } 154 } 155}; 156 157void ObbActionListener::onObbResult(const android::String16& filename, const int32_t nonce, const int32_t state) { 158 mStorageManager->fireCallback(String8(filename).string(), nonce, state); 159} 160 161 162AStorageManager* AStorageManager_new() { 163 sp<AStorageManager> mgr = new AStorageManager(); 164 if (mgr == NULL || !mgr->initialize()) { 165 return NULL; 166 } 167 mgr->incStrong((void*)AStorageManager_new); 168 return static_cast<AStorageManager*>(mgr.get()); 169} 170 171void AStorageManager_delete(AStorageManager* mgr) { 172 if (mgr) { 173 mgr->decStrong((void*)AStorageManager_new); 174 } 175} 176 177void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key, 178 AStorageManager_obbCallbackFunc cb, void* data) { 179 mgr->mountObb(filename, key, cb, data); 180} 181 182void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force, 183 AStorageManager_obbCallbackFunc cb, void* data) { 184 mgr->unmountObb(filename, force != 0, cb, data); 185} 186 187int AStorageManager_isObbMounted(AStorageManager* mgr, const char* filename) { 188 return mgr->isObbMounted(filename) != 0; 189} 190 191const char* AStorageManager_getMountedObbPath(AStorageManager* mgr, const char* filename) { 192 return mgr->getMountedObbPath(filename); 193} 194