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 #define LOG_TAG "SharedRegionParcelable"
18 //#define LOG_NDEBUG 0
19 #include <utils/Log.h>
20 
21 #include <stdint.h>
22 
23 #include <sys/mman.h>
24 #include <binder/Parcelable.h>
25 
26 #include <aaudio/AAudio.h>
27 #include <utility/AAudioUtilities.h>
28 
29 #include "binding/SharedMemoryParcelable.h"
30 #include "binding/SharedRegionParcelable.h"
31 
32 using android::NO_ERROR;
33 using android::status_t;
34 using android::Parcel;
35 using android::Parcelable;
36 
37 using namespace aaudio;
38 
SharedRegionParcelable()39 SharedRegionParcelable::SharedRegionParcelable() {}
~SharedRegionParcelable()40 SharedRegionParcelable::~SharedRegionParcelable() {}
41 
setup(int32_t sharedMemoryIndex,int32_t offsetInBytes,int32_t sizeInBytes)42 void SharedRegionParcelable::setup(int32_t sharedMemoryIndex,
43                                    int32_t offsetInBytes,
44                                    int32_t sizeInBytes) {
45     mSharedMemoryIndex = sharedMemoryIndex;
46     mOffsetInBytes = offsetInBytes;
47     mSizeInBytes = sizeInBytes;
48 }
49 
writeToParcel(Parcel * parcel) const50 status_t SharedRegionParcelable::writeToParcel(Parcel* parcel) const {
51     status_t status = AAudioConvert_aaudioToAndroidStatus(validate());
52     if (status != NO_ERROR) goto error;
53 
54     status = parcel->writeInt32(mSizeInBytes);
55     if (status != NO_ERROR) goto error;
56     if (mSizeInBytes > 0) {
57         status = parcel->writeInt32(mSharedMemoryIndex);
58         if (status != NO_ERROR) goto error;
59         status = parcel->writeInt32(mOffsetInBytes);
60         if (status != NO_ERROR) goto error;
61     }
62     return NO_ERROR;
63 
64 error:
65     ALOGE("%s returning %d", __func__, status);
66     return status;
67 }
68 
readFromParcel(const Parcel * parcel)69 status_t SharedRegionParcelable::readFromParcel(const Parcel* parcel) {
70     status_t status = parcel->readInt32(&mSizeInBytes);
71     if (status != NO_ERROR) goto error;
72     if (mSizeInBytes > 0) {
73         status = parcel->readInt32(&mSharedMemoryIndex);
74         if (status != NO_ERROR) goto error;
75         status = parcel->readInt32(&mOffsetInBytes);
76         if (status != NO_ERROR) goto error;
77     }
78     return AAudioConvert_aaudioToAndroidStatus(validate());
79 
80 error:
81     ALOGE("%s returning %d", __func__, status);
82     return status;
83 }
84 
resolve(SharedMemoryParcelable * memoryParcels,void ** regionAddressPtr)85 aaudio_result_t SharedRegionParcelable::resolve(SharedMemoryParcelable *memoryParcels,
86                                               void **regionAddressPtr) {
87     if (mSizeInBytes == 0) {
88         *regionAddressPtr = nullptr;
89         return AAUDIO_OK;
90     }
91     if (mSharedMemoryIndex < 0) {
92         ALOGE("invalid mSharedMemoryIndex = %d", mSharedMemoryIndex);
93         return AAUDIO_ERROR_INTERNAL;
94     }
95     SharedMemoryParcelable *memoryParcel = &memoryParcels[mSharedMemoryIndex];
96     return memoryParcel->resolve(mOffsetInBytes, mSizeInBytes, regionAddressPtr);
97 }
98 
validate() const99 aaudio_result_t SharedRegionParcelable::validate() const {
100     if (mSizeInBytes < 0 || mSizeInBytes >= MAX_MMAP_SIZE_BYTES) {
101         ALOGE("invalid mSizeInBytes = %d", mSizeInBytes);
102         return AAUDIO_ERROR_OUT_OF_RANGE;
103     }
104     if (mSizeInBytes > 0) {
105         if (mOffsetInBytes < 0 || mOffsetInBytes >= MAX_MMAP_OFFSET_BYTES) {
106             ALOGE("invalid mOffsetInBytes = %d", mOffsetInBytes);
107             return AAUDIO_ERROR_OUT_OF_RANGE;
108         }
109         if (mSharedMemoryIndex < 0 || mSharedMemoryIndex >= MAX_SHARED_MEMORIES) {
110             ALOGE("invalid mSharedMemoryIndex = %d", mSharedMemoryIndex);
111             return AAUDIO_ERROR_INTERNAL;
112         }
113     }
114     return AAUDIO_OK;
115 }
116 
dump()117 void SharedRegionParcelable::dump() {
118     ALOGD("mSizeInBytes = %d -----", mSizeInBytes);
119     if (mSizeInBytes > 0) {
120         ALOGD("mSharedMemoryIndex = %d", mSharedMemoryIndex);
121         ALOGD("mOffsetInBytes = %d", mOffsetInBytes);
122     }
123 }
124