1086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root/*
2086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root * Copyright (C) 2010 The Android Open Source Project
3086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root *
4086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root * Licensed under the Apache License, Version 2.0 (the "License");
5086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root * you may not use this file except in compliance with the License.
6086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root * You may obtain a copy of the License at
7086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root *
8086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root *      http://www.apache.org/licenses/LICENSE-2.0
9086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root *
10086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root * Unless required by applicable law or agreed to in writing, software
11086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root * distributed under the License is distributed on an "AS IS" BASIS,
12086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root * See the License for the specific language governing permissions and
14086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root * limitations under the License.
15086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root */
16086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
17086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root#define LOG_TAG "NStorage"
18086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
19086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root#include <android/storage_manager.h>
20086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root#include <storage/IMountService.h>
21086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
22086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root#include <binder/Binder.h>
23086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root#include <binder/IServiceManager.h>
24af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root#include <utils/Atomic.h>
25086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root#include <utils/Log.h>
26086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root#include <utils/RefBase.h>
27086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root#include <utils/String8.h>
28086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root#include <utils/String16.h>
29af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root#include <utils/Vector.h>
30af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root#include <utils/threads.h>
31086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
32086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
33086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Rootusing namespace android;
34086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
35086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Rootstruct ObbActionListener : public BnObbActionListener {
36086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Rootprivate:
37086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    sp<AStorageManager> mStorageManager;
38086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
39086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Rootpublic:
40086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    ObbActionListener(AStorageManager* mgr) :
41086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root            mStorageManager(mgr)
42086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    {}
43086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
44af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    virtual void onObbResult(const android::String16& filename, const int32_t nonce,
45af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            const int32_t state);
46af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root};
47af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root
48af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Rootclass ObbCallback {
49af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Rootpublic:
50af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    ObbCallback(int32_t _nonce, AStorageManager_obbCallbackFunc _cb, void* _data)
51af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            : nonce(_nonce)
52af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            , cb(_cb)
53af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            , data(_data)
54af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    {}
55af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root
56af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    int32_t nonce;
57af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    AStorageManager_obbCallbackFunc cb;
58af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    void* data;
59086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root};
60086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
61086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Rootstruct AStorageManager : public RefBase {
62086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Rootprotected:
63af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    Mutex mCallbackLock;
64af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    Vector<ObbCallback*> mCallbacks;
65af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    volatile int32_t mNextNonce;
66086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    sp<ObbActionListener> mObbActionListener;
67086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    sp<IMountService> mMountService;
68086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
69af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    int32_t getNextNonce() {
70af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        return android_atomic_inc(&mNextNonce);
71af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    }
72af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root
73af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    ObbCallback* registerObbCallback(AStorageManager_obbCallbackFunc func, void* data) {
74af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        ObbCallback* cb = new ObbCallback(getNextNonce(), func, data);
75af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        {
76af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            AutoMutex _l(mCallbackLock);
77af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            mCallbacks.push(cb);
78af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        }
79af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        return cb;
80af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    }
81af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root
82086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Rootpublic:
8305105f7abe02b2dff91d6260b3628c8b97816babKenny Root    AStorageManager()
84086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    {
85086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    }
86086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
87086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    bool initialize() {
88086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        sp<IServiceManager> sm = defaultServiceManager();
89086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        if (sm == NULL) {
90086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root            LOGE("Couldn't get default ServiceManager\n");
91086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root            return false;
92086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        }
93086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
94086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        mMountService = interface_cast<IMountService>(sm->getService(String16("mount")));
95086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        if (mMountService == NULL) {
96086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root            LOGE("Couldn't get connection to MountService\n");
97086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root            return false;
98086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        }
99086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
100086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        mObbActionListener = new ObbActionListener(this);
101086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
102086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        return true;
103086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    }
104086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
105af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    void fireCallback(const char* filename, const int32_t nonce, const int32_t state) {
106af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        ObbCallback* target = NULL;
107af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        {
108af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            AutoMutex _l(mCallbackLock);
109af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            int N = mCallbacks.size();
110af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            for (int i = 0; i < N; i++) {
111af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root                ObbCallback* cb = mCallbacks.editItemAt(i);
112af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root                if (cb->nonce == nonce) {
113af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root                    target = cb;
114af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root                    mCallbacks.removeAt(i);
115af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root                    break;
116af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root                }
117af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            }
118af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        }
11905105f7abe02b2dff91d6260b3628c8b97816babKenny Root
120af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        if (target != NULL) {
121af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            target->cb(filename, state, target->data);
122af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            delete target;
123af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        } else {
124af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root            LOGI("Didn't find the callback handler for: %s\n", filename);
12505105f7abe02b2dff91d6260b3628c8b97816babKenny Root        }
126086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    }
127086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
128af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    void mountObb(const char* filename, const char* key, AStorageManager_obbCallbackFunc func, void* data) {
129af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        ObbCallback* cb = registerObbCallback(func, data);
130086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        String16 filename16(filename);
131086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        String16 key16(key);
132af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        mMountService->mountObb(filename16, key16, mObbActionListener, cb->nonce);
133086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    }
134086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
135af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    void unmountObb(const char* filename, const bool force, AStorageManager_obbCallbackFunc func, void* data) {
136af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        ObbCallback* cb = registerObbCallback(func, data);
137086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        String16 filename16(filename);
138af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        mMountService->unmountObb(filename16, force, mObbActionListener, cb->nonce);
139086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    }
140086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
141086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    int isObbMounted(const char* filename) {
142086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        String16 filename16(filename);
143086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        return mMountService->isObbMounted(filename16);
144086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    }
145086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
146086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    const char* getMountedObbPath(const char* filename) {
147086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        String16 filename16(filename);
148086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        String16 path16;
149086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        if (mMountService->getMountedObbPath(filename16, path16)) {
150086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root            return String8(path16).string();
151086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        } else {
152086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root            return NULL;
153086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        }
154086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    }
155086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root};
156086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
157af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Rootvoid ObbActionListener::onObbResult(const android::String16& filename, const int32_t nonce, const int32_t state) {
158af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    mStorageManager->fireCallback(String8(filename).string(), nonce, state);
15905105f7abe02b2dff91d6260b3628c8b97816babKenny Root}
16005105f7abe02b2dff91d6260b3628c8b97816babKenny Root
161086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
162086d084dd9deab4350981da5e48c8bda5e88fb75Kenny RootAStorageManager* AStorageManager_new() {
163086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    sp<AStorageManager> mgr = new AStorageManager();
164086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    if (mgr == NULL || !mgr->initialize()) {
165086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        return NULL;
166086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    }
167086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    mgr->incStrong((void*)AStorageManager_new);
168086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    return static_cast<AStorageManager*>(mgr.get());
169086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root}
170086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
171086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Rootvoid AStorageManager_delete(AStorageManager* mgr) {
172086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    if (mgr) {
173086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root        mgr->decStrong((void*)AStorageManager_new);
174086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    }
175086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root}
176086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
177af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Rootvoid AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key,
178af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        AStorageManager_obbCallbackFunc cb, void* data) {
179af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    mgr->mountObb(filename, key, cb, data);
180086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root}
181086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
182af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Rootvoid AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force,
183af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root        AStorageManager_obbCallbackFunc cb, void* data) {
184af9d667ccf3e24058214cf4cc0a8aa8bc5100e3cKenny Root    mgr->unmountObb(filename, force != 0, cb, data);
185086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root}
186086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
187086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Rootint AStorageManager_isObbMounted(AStorageManager* mgr, const char* filename) {
188086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    return mgr->isObbMounted(filename) != 0;
189086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root}
190086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root
191086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Rootconst char* AStorageManager_getMountedObbPath(AStorageManager* mgr, const char* filename) {
192086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root    return mgr->getMountedObbPath(filename);
193086d084dd9deab4350981da5e48c8bda5e88fb75Kenny Root}
194