blob: 399f1ffcb594ce95e8fad9ad41e9f6451cafafbf [file] [log] [blame]
Kenny Root086d0842010-08-19 17:55:56 -07001/*
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>
Kenny Rootaf9d6672010-10-08 09:21:39 -070024#include <utils/Atomic.h>
Kenny Root086d0842010-08-19 17:55:56 -070025#include <utils/Log.h>
26#include <utils/RefBase.h>
27#include <utils/String8.h>
28#include <utils/String16.h>
Kenny Rootaf9d6672010-10-08 09:21:39 -070029#include <utils/Vector.h>
30#include <utils/threads.h>
Kenny Root086d0842010-08-19 17:55:56 -070031
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
Kenny Rootaf9d6672010-10-08 09:21:39 -070044 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;
Kenny Root086d0842010-08-19 17:55:56 -070059};
60
61struct AStorageManager : public RefBase {
62protected:
Kenny Rootaf9d6672010-10-08 09:21:39 -070063 Mutex mCallbackLock;
64 Vector<ObbCallback*> mCallbacks;
65 volatile int32_t mNextNonce;
Kenny Root086d0842010-08-19 17:55:56 -070066 sp<ObbActionListener> mObbActionListener;
67 sp<IMountService> mMountService;
68
Kenny Rootaf9d6672010-10-08 09:21:39 -070069 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
Kenny Root086d0842010-08-19 17:55:56 -070082public:
Kenny Root05105f72010-09-22 17:29:43 -070083 AStorageManager()
Kenny Root086d0842010-08-19 17:55:56 -070084 {
85 }
86
87 bool initialize() {
88 sp<IServiceManager> sm = defaultServiceManager();
89 if (sm == NULL) {
Steve Block3762c312012-01-06 19:20:56 +000090 ALOGE("Couldn't get default ServiceManager\n");
Kenny Root086d0842010-08-19 17:55:56 -070091 return false;
92 }
93
94 mMountService = interface_cast<IMountService>(sm->getService(String16("mount")));
95 if (mMountService == NULL) {
Steve Block3762c312012-01-06 19:20:56 +000096 ALOGE("Couldn't get connection to MountService\n");
Kenny Root086d0842010-08-19 17:55:56 -070097 return false;
98 }
99
100 mObbActionListener = new ObbActionListener(this);
101
102 return true;
103 }
104
Kenny Rootaf9d6672010-10-08 09:21:39 -0700105 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 }
Kenny Root05105f72010-09-22 17:29:43 -0700119
Kenny Rootaf9d6672010-10-08 09:21:39 -0700120 if (target != NULL) {
121 target->cb(filename, state, target->data);
122 delete target;
123 } else {
Steve Block6215d3f2012-01-04 20:05:49 +0000124 ALOGI("Didn't find the callback handler for: %s\n", filename);
Kenny Root05105f72010-09-22 17:29:43 -0700125 }
Kenny Root086d0842010-08-19 17:55:56 -0700126 }
127
Jeff Sharkey4fbbda42012-09-24 18:34:07 -0700128 void mountObb(const char* rawPath, const char* key, AStorageManager_obbCallbackFunc func,
129 void* data) {
130 // Resolve path before sending to MountService
131 char canonicalPath[PATH_MAX];
132 if (realpath(rawPath, canonicalPath) == NULL) {
133 ALOGE("mountObb failed to resolve path %s: %s", rawPath, strerror(errno));
134 return;
135 }
136
Kenny Rootaf9d6672010-10-08 09:21:39 -0700137 ObbCallback* cb = registerObbCallback(func, data);
Jeff Sharkey4fbbda42012-09-24 18:34:07 -0700138 String16 rawPath16(rawPath);
139 String16 canonicalPath16(canonicalPath);
Kenny Root086d0842010-08-19 17:55:56 -0700140 String16 key16(key);
Jeff Sharkey4fbbda42012-09-24 18:34:07 -0700141 mMountService->mountObb(rawPath16, canonicalPath16, key16, mObbActionListener, cb->nonce);
Kenny Root086d0842010-08-19 17:55:56 -0700142 }
143
Kenny Rootaf9d6672010-10-08 09:21:39 -0700144 void unmountObb(const char* filename, const bool force, AStorageManager_obbCallbackFunc func, void* data) {
145 ObbCallback* cb = registerObbCallback(func, data);
Kenny Root086d0842010-08-19 17:55:56 -0700146 String16 filename16(filename);
Kenny Rootaf9d6672010-10-08 09:21:39 -0700147 mMountService->unmountObb(filename16, force, mObbActionListener, cb->nonce);
Kenny Root086d0842010-08-19 17:55:56 -0700148 }
149
150 int isObbMounted(const char* filename) {
151 String16 filename16(filename);
152 return mMountService->isObbMounted(filename16);
153 }
154
155 const char* getMountedObbPath(const char* filename) {
156 String16 filename16(filename);
157 String16 path16;
158 if (mMountService->getMountedObbPath(filename16, path16)) {
159 return String8(path16).string();
160 } else {
161 return NULL;
162 }
163 }
164};
165
Kenny Rootaf9d6672010-10-08 09:21:39 -0700166void ObbActionListener::onObbResult(const android::String16& filename, const int32_t nonce, const int32_t state) {
167 mStorageManager->fireCallback(String8(filename).string(), nonce, state);
Kenny Root05105f72010-09-22 17:29:43 -0700168}
169
Kenny Root086d0842010-08-19 17:55:56 -0700170
171AStorageManager* AStorageManager_new() {
172 sp<AStorageManager> mgr = new AStorageManager();
173 if (mgr == NULL || !mgr->initialize()) {
174 return NULL;
175 }
176 mgr->incStrong((void*)AStorageManager_new);
177 return static_cast<AStorageManager*>(mgr.get());
178}
179
180void AStorageManager_delete(AStorageManager* mgr) {
181 if (mgr) {
182 mgr->decStrong((void*)AStorageManager_new);
183 }
184}
185
Kenny Rootaf9d6672010-10-08 09:21:39 -0700186void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key,
187 AStorageManager_obbCallbackFunc cb, void* data) {
188 mgr->mountObb(filename, key, cb, data);
Kenny Root086d0842010-08-19 17:55:56 -0700189}
190
Kenny Rootaf9d6672010-10-08 09:21:39 -0700191void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force,
192 AStorageManager_obbCallbackFunc cb, void* data) {
193 mgr->unmountObb(filename, force != 0, cb, data);
Kenny Root086d0842010-08-19 17:55:56 -0700194}
195
196int AStorageManager_isObbMounted(AStorageManager* mgr, const char* filename) {
197 return mgr->isObbMounted(filename) != 0;
198}
199
200const char* AStorageManager_getMountedObbPath(AStorageManager* mgr, const char* filename) {
201 return mgr->getMountedObbPath(filename);
202}