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 33 using namespace android; 34 35 struct ObbActionListener : public BnObbActionListener { 36 private: 37 sp<AStorageManager> mStorageManager; 38 39 public: 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 48 class ObbCallback { 49 public: 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 61 struct AStorageManager : public RefBase { 62 protected: 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 82 public: 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 LOGI("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 157 void 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 162 AStorageManager* 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 171 void AStorageManager_delete(AStorageManager* mgr) { 172 if (mgr) { 173 mgr->decStrong((void*)AStorageManager_new); 174 } 175 } 176 177 void 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 182 void 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 187 int AStorageManager_isObbMounted(AStorageManager* mgr, const char* filename) { 188 return mgr->isObbMounted(filename) != 0; 189 } 190 191 const char* AStorageManager_getMountedObbPath(AStorageManager* mgr, const char* filename) { 192 return mgr->getMountedObbPath(filename); 193 } 194