SharedMemoryParcelable.cpp revision f53e613b3dedab3ecada2c93d8846233c442d129
1/*
2 * Copyright 2016 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#include <stdint.h>
18
19#include <sys/mman.h>
20#include <aaudio/AAudioDefinitions.h>
21
22#include <binder/Parcelable.h>
23
24#include "binding/SharedMemoryParcelable.h"
25
26using android::NO_ERROR;
27using android::status_t;
28using android::Parcel;
29using android::Parcelable;
30
31using namespace aaudio;
32
33SharedMemoryParcelable::SharedMemoryParcelable() {}
34SharedMemoryParcelable::~SharedMemoryParcelable() {};
35
36void SharedMemoryParcelable::setup(int fd, int32_t sizeInBytes) {
37    mFd = fd;
38    mSizeInBytes = sizeInBytes;
39}
40
41status_t SharedMemoryParcelable::writeToParcel(Parcel* parcel) const {
42    parcel->writeInt32(mSizeInBytes);
43    if (mSizeInBytes > 0) {
44        parcel->writeDupFileDescriptor(mFd);
45    }
46    return NO_ERROR; // TODO check for errors above
47}
48
49status_t SharedMemoryParcelable::readFromParcel(const Parcel* parcel) {
50    parcel->readInt32(&mSizeInBytes);
51    if (mSizeInBytes > 0) {
52        mFd = dup(parcel->readFileDescriptor());
53    }
54    return NO_ERROR; // TODO check for errors above
55}
56
57// TODO Add code to unmmap()
58
59aaudio_result_t SharedMemoryParcelable::resolve(int32_t offsetInBytes, int32_t sizeInBytes,
60                                              void **regionAddressPtr) {
61    if (offsetInBytes < 0) {
62        ALOGE("SharedMemoryParcelable illegal offsetInBytes = %d", offsetInBytes);
63        return AAUDIO_ERROR_OUT_OF_RANGE;
64    } else if ((offsetInBytes + sizeInBytes) > mSizeInBytes) {
65        ALOGE("SharedMemoryParcelable out of range, offsetInBytes = %d, "
66              "sizeInBytes = %d, mSizeInBytes = %d",
67              offsetInBytes, sizeInBytes, mSizeInBytes);
68        return AAUDIO_ERROR_OUT_OF_RANGE;
69    }
70    if (mResolvedAddress == nullptr) {
71        mResolvedAddress = (uint8_t *) mmap(0, mSizeInBytes, PROT_READ|PROT_WRITE,
72                                          MAP_SHARED, mFd, 0);
73        if (mResolvedAddress == nullptr) {
74            ALOGE("SharedMemoryParcelable mmap failed for fd = %d", mFd);
75            return AAUDIO_ERROR_INTERNAL;
76        }
77    }
78    *regionAddressPtr = mResolvedAddress + offsetInBytes;
79    ALOGD("SharedMemoryParcelable mResolvedAddress = %p", mResolvedAddress);
80    ALOGD("SharedMemoryParcelable offset by %d, *regionAddressPtr = %p",
81          offsetInBytes, *regionAddressPtr);
82    return AAUDIO_OK;
83}
84
85int32_t SharedMemoryParcelable::getSizeInBytes() {
86    return mSizeInBytes;
87}
88
89aaudio_result_t SharedMemoryParcelable::validate() {
90    if (mSizeInBytes < 0 || mSizeInBytes >= MAX_MMAP_SIZE_BYTES) {
91        ALOGE("SharedMemoryParcelable invalid mSizeInBytes = %d", mSizeInBytes);
92        return AAUDIO_ERROR_OUT_OF_RANGE;
93    }
94    if (mSizeInBytes > 0) {
95        if (mFd == -1) {
96            ALOGE("SharedMemoryParcelable uninitialized mFd = %d", mFd);
97            return AAUDIO_ERROR_INTERNAL;
98        }
99    }
100    return AAUDIO_OK;
101}
102
103void SharedMemoryParcelable::dump() {
104    ALOGD("SharedMemoryParcelable mFd = %d", mFd);
105    ALOGD("SharedMemoryParcelable mSizeInBytes = %d", mSizeInBytes);
106    ALOGD("SharedMemoryParcelable mResolvedAddress = %p", mResolvedAddress);
107}
108