blob: 22725254fef6b83de5f60358e14ede1d57ecc048 [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>
Sudheer Shanka25469aa2018-08-27 15:50:23 -070021#include <storage/ObbInfo.h>
Kenny Root086d0842010-08-19 17:55:56 -070022
Sudheer Shanka25469aa2018-08-27 15:50:23 -070023#include <androidfw/ObbFile.h>
Kenny Root086d0842010-08-19 17:55:56 -070024#include <binder/Binder.h>
25#include <binder/IServiceManager.h>
Steven Morelandfb7952f2018-02-23 14:58:50 -080026#include <cutils/atomic.h>
Kenny Root086d0842010-08-19 17:55:56 -070027#include <utils/Log.h>
28#include <utils/RefBase.h>
29#include <utils/String8.h>
30#include <utils/String16.h>
Kenny Rootaf9d6672010-10-08 09:21:39 -070031#include <utils/Vector.h>
32#include <utils/threads.h>
Kenny Root086d0842010-08-19 17:55:56 -070033
Kenny Root086d0842010-08-19 17:55:56 -070034using namespace android;
35
36struct ObbActionListener : public BnObbActionListener {
37private:
38 sp<AStorageManager> mStorageManager;
39
40public:
Chih-Hung Hsiehc6baf562016-04-27 11:29:23 -070041 explicit ObbActionListener(AStorageManager* mgr) :
Kenny Root086d0842010-08-19 17:55:56 -070042 mStorageManager(mgr)
43 {}
44
Kenny Rootaf9d6672010-10-08 09:21:39 -070045 virtual void onObbResult(const android::String16& filename, const int32_t nonce,
46 const int32_t state);
47};
48
49class ObbCallback {
50public:
51 ObbCallback(int32_t _nonce, AStorageManager_obbCallbackFunc _cb, void* _data)
52 : nonce(_nonce)
53 , cb(_cb)
54 , data(_data)
55 {}
56
57 int32_t nonce;
58 AStorageManager_obbCallbackFunc cb;
59 void* data;
Kenny Root086d0842010-08-19 17:55:56 -070060};
61
62struct AStorageManager : public RefBase {
63protected:
Kenny Rootaf9d6672010-10-08 09:21:39 -070064 Mutex mCallbackLock;
65 Vector<ObbCallback*> mCallbacks;
66 volatile int32_t mNextNonce;
Kenny Root086d0842010-08-19 17:55:56 -070067 sp<ObbActionListener> mObbActionListener;
68 sp<IMountService> mMountService;
69
Kenny Rootaf9d6672010-10-08 09:21:39 -070070 int32_t getNextNonce() {
71 return android_atomic_inc(&mNextNonce);
72 }
73
74 ObbCallback* registerObbCallback(AStorageManager_obbCallbackFunc func, void* data) {
75 ObbCallback* cb = new ObbCallback(getNextNonce(), func, data);
76 {
77 AutoMutex _l(mCallbackLock);
78 mCallbacks.push(cb);
79 }
80 return cb;
81 }
82
Sudheer Shanka25469aa2018-08-27 15:50:23 -070083 ObbInfo* getObbInfo(char* canonicalPath) {
84 sp<ObbFile> obbFile = new ObbFile();
85 if (!obbFile->readFrom(canonicalPath)) {
86 return nullptr;
87 }
88
89 String16 fileName(obbFile->getFileName());
90 String16 packageName(obbFile->getPackageName());
91 size_t length;
92 const unsigned char* salt = obbFile->getSalt(&length);
93 return new ObbInfo(fileName, packageName,
94 obbFile->getVersion(), obbFile->getFlags(), length, salt);
95 }
96
Kenny Root086d0842010-08-19 17:55:56 -070097public:
Kenny Root05105f72010-09-22 17:29:43 -070098 AStorageManager()
Kenny Root086d0842010-08-19 17:55:56 -070099 {
100 }
101
102 bool initialize() {
103 sp<IServiceManager> sm = defaultServiceManager();
104 if (sm == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000105 ALOGE("Couldn't get default ServiceManager\n");
Kenny Root086d0842010-08-19 17:55:56 -0700106 return false;
107 }
108
109 mMountService = interface_cast<IMountService>(sm->getService(String16("mount")));
110 if (mMountService == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000111 ALOGE("Couldn't get connection to MountService\n");
Kenny Root086d0842010-08-19 17:55:56 -0700112 return false;
113 }
114
115 mObbActionListener = new ObbActionListener(this);
116
117 return true;
118 }
119
Kenny Rootaf9d6672010-10-08 09:21:39 -0700120 void fireCallback(const char* filename, const int32_t nonce, const int32_t state) {
121 ObbCallback* target = NULL;
122 {
123 AutoMutex _l(mCallbackLock);
124 int N = mCallbacks.size();
125 for (int i = 0; i < N; i++) {
126 ObbCallback* cb = mCallbacks.editItemAt(i);
127 if (cb->nonce == nonce) {
128 target = cb;
129 mCallbacks.removeAt(i);
130 break;
131 }
132 }
133 }
Kenny Root05105f72010-09-22 17:29:43 -0700134
Kenny Rootaf9d6672010-10-08 09:21:39 -0700135 if (target != NULL) {
136 target->cb(filename, state, target->data);
137 delete target;
138 } else {
Steve Block6215d3f2012-01-04 20:05:49 +0000139 ALOGI("Didn't find the callback handler for: %s\n", filename);
Kenny Root05105f72010-09-22 17:29:43 -0700140 }
Kenny Root086d0842010-08-19 17:55:56 -0700141 }
142
Jeff Sharkey4fbbda42012-09-24 18:34:07 -0700143 void mountObb(const char* rawPath, const char* key, AStorageManager_obbCallbackFunc func,
144 void* data) {
145 // Resolve path before sending to MountService
146 char canonicalPath[PATH_MAX];
147 if (realpath(rawPath, canonicalPath) == NULL) {
148 ALOGE("mountObb failed to resolve path %s: %s", rawPath, strerror(errno));
149 return;
150 }
151
Sudheer Shanka25469aa2018-08-27 15:50:23 -0700152 sp<ObbInfo> obbInfo = getObbInfo(canonicalPath);
153 if (obbInfo == nullptr) {
154 ALOGE("Couldn't get obb info for %s: %s", canonicalPath, strerror(errno));
155 return;
156 }
157
Kenny Rootaf9d6672010-10-08 09:21:39 -0700158 ObbCallback* cb = registerObbCallback(func, data);
Jeff Sharkey4fbbda42012-09-24 18:34:07 -0700159 String16 rawPath16(rawPath);
160 String16 canonicalPath16(canonicalPath);
Kenny Root086d0842010-08-19 17:55:56 -0700161 String16 key16(key);
Sudheer Shanka25469aa2018-08-27 15:50:23 -0700162 mMountService->mountObb(rawPath16, canonicalPath16, key16, mObbActionListener,
163 cb->nonce, obbInfo);
Kenny Root086d0842010-08-19 17:55:56 -0700164 }
165
Kenny Rootaf9d6672010-10-08 09:21:39 -0700166 void unmountObb(const char* filename, const bool force, AStorageManager_obbCallbackFunc func, void* data) {
167 ObbCallback* cb = registerObbCallback(func, data);
Kenny Root086d0842010-08-19 17:55:56 -0700168 String16 filename16(filename);
Kenny Rootaf9d6672010-10-08 09:21:39 -0700169 mMountService->unmountObb(filename16, force, mObbActionListener, cb->nonce);
Kenny Root086d0842010-08-19 17:55:56 -0700170 }
171
172 int isObbMounted(const char* filename) {
173 String16 filename16(filename);
174 return mMountService->isObbMounted(filename16);
175 }
176
177 const char* getMountedObbPath(const char* filename) {
178 String16 filename16(filename);
179 String16 path16;
180 if (mMountService->getMountedObbPath(filename16, path16)) {
181 return String8(path16).string();
182 } else {
183 return NULL;
184 }
185 }
186};
187
Kenny Rootaf9d6672010-10-08 09:21:39 -0700188void ObbActionListener::onObbResult(const android::String16& filename, const int32_t nonce, const int32_t state) {
189 mStorageManager->fireCallback(String8(filename).string(), nonce, state);
Kenny Root05105f72010-09-22 17:29:43 -0700190}
191
Kenny Root086d0842010-08-19 17:55:56 -0700192
193AStorageManager* AStorageManager_new() {
194 sp<AStorageManager> mgr = new AStorageManager();
195 if (mgr == NULL || !mgr->initialize()) {
196 return NULL;
197 }
198 mgr->incStrong((void*)AStorageManager_new);
199 return static_cast<AStorageManager*>(mgr.get());
200}
201
202void AStorageManager_delete(AStorageManager* mgr) {
203 if (mgr) {
204 mgr->decStrong((void*)AStorageManager_new);
205 }
206}
207
Kenny Rootaf9d6672010-10-08 09:21:39 -0700208void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key,
209 AStorageManager_obbCallbackFunc cb, void* data) {
210 mgr->mountObb(filename, key, cb, data);
Kenny Root086d0842010-08-19 17:55:56 -0700211}
212
Kenny Rootaf9d6672010-10-08 09:21:39 -0700213void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force,
214 AStorageManager_obbCallbackFunc cb, void* data) {
215 mgr->unmountObb(filename, force != 0, cb, data);
Kenny Root086d0842010-08-19 17:55:56 -0700216}
217
218int AStorageManager_isObbMounted(AStorageManager* mgr, const char* filename) {
219 return mgr->isObbMounted(filename) != 0;
220}
221
222const char* AStorageManager_getMountedObbPath(AStorageManager* mgr, const char* filename) {
223 return mgr->getMountedObbPath(filename);
224}