SharedMemoryParcelable.cpp revision a4eb0d86a29be2763be5fac51727858d5095794b
1204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk/*
2204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * Copyright 2016 The Android Open Source Project
3204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *
4204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * Licensed under the Apache License, Version 2.0 (the "License");
5204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * you may not use this file except in compliance with the License.
6204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * You may obtain a copy of the License at
7204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *
8204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *      http://www.apache.org/licenses/LICENSE-2.0
9204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *
10204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * Unless required by applicable law or agreed to in writing, software
11204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * distributed under the License is distributed on an "AS IS" BASIS,
12204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * See the License for the specific language governing permissions and
14204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * limitations under the License.
15204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk */
16204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
17c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#define LOG_TAG "AAudio"
18c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk//#define LOG_NDEBUG 0
19c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <utils/Log.h>
20c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
21204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk#include <stdint.h>
22c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <stdio.h>
23204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
24204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk#include <sys/mman.h>
25a4eb0d86a29be2763be5fac51727858d5095794bPhil Burk#include <aaudio/AAudio.h>
26204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
27204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk#include <binder/Parcelable.h>
28c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <utility/AAudioUtilities.h>
29204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
30204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk#include "binding/SharedMemoryParcelable.h"
31204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
32204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkusing android::NO_ERROR;
33204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkusing android::status_t;
34204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkusing android::Parcel;
35204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkusing android::Parcelable;
36204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
375ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkusing namespace aaudio;
38204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
39204a163c86f357a878873fe7d4c4164f3d55c9b6Phil BurkSharedMemoryParcelable::SharedMemoryParcelable() {}
40204a163c86f357a878873fe7d4c4164f3d55c9b6Phil BurkSharedMemoryParcelable::~SharedMemoryParcelable() {};
41204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
42204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkvoid SharedMemoryParcelable::setup(int fd, int32_t sizeInBytes) {
43204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    mFd = fd;
44204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    mSizeInBytes = sizeInBytes;
45c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
46204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk}
47204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
48204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkstatus_t SharedMemoryParcelable::writeToParcel(Parcel* parcel) const {
49c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    status_t status = parcel->writeInt32(mSizeInBytes);
50c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (status != NO_ERROR) return status;
51204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    if (mSizeInBytes > 0) {
52c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        status = parcel->writeDupFileDescriptor(mFd);
53c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        ALOGE_IF(status != NO_ERROR, "SharedMemoryParcelable writeDupFileDescriptor failed : %d", status);
54204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
55c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return status;
56204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk}
57204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
58204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkstatus_t SharedMemoryParcelable::readFromParcel(const Parcel* parcel) {
59c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    status_t status = parcel->readInt32(&mSizeInBytes);
60c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (status != NO_ERROR) {
61c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return status;
62c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
63204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    if (mSizeInBytes > 0) {
64c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk// FIXME        mFd = dup(parcel->readFileDescriptor());
65c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        // Why is the ALSA resource not getting freed?!
66c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        mFd = fcntl(parcel->readFileDescriptor(), F_DUPFD_CLOEXEC, 0);
67c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        if (mFd == -1) {
68c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            status = -errno;
69c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGE("SharedMemoryParcelable readFileDescriptor fcntl() failed : %d", status);
70c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        }
71204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
72c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return status;
73204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk}
74204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
75c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t SharedMemoryParcelable::close() {
76c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (mResolvedAddress != nullptr) {
77c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        int err = munmap(mResolvedAddress, mSizeInBytes);
78c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        if (err < 0) {
79c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGE("SharedMemoryParcelable::close() munmap() failed %d", err);
80c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            return AAudioConvert_androidToAAudioResult(err);
81c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        }
82c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        mResolvedAddress = nullptr;
83c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
84c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (mFd != -1) {
85c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        ::close(mFd);
86c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        mFd = -1;
87c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
88c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return AAUDIO_OK;
89c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
90204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
915ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t SharedMemoryParcelable::resolve(int32_t offsetInBytes, int32_t sizeInBytes,
92204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk                                              void **regionAddressPtr) {
93c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
94204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    if (offsetInBytes < 0) {
95204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        ALOGE("SharedMemoryParcelable illegal offsetInBytes = %d", offsetInBytes);
965ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_ERROR_OUT_OF_RANGE;
97204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    } else if ((offsetInBytes + sizeInBytes) > mSizeInBytes) {
98204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        ALOGE("SharedMemoryParcelable out of range, offsetInBytes = %d, "
99204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk              "sizeInBytes = %d, mSizeInBytes = %d",
100204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk              offsetInBytes, sizeInBytes, mSizeInBytes);
1015ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_ERROR_OUT_OF_RANGE;
102204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
103204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    if (mResolvedAddress == nullptr) {
104c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        /* TODO remove
105c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        int fd = fcntl(mFd, F_DUPFD_CLOEXEC, 0);
106c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%zd, (%s)",
107c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                    mFd, mSizeInBytes, strerror(errno));
108c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        */
109204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        mResolvedAddress = (uint8_t *) mmap(0, mSizeInBytes, PROT_READ|PROT_WRITE,
110204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk                                          MAP_SHARED, mFd, 0);
111204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        if (mResolvedAddress == nullptr) {
112204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            ALOGE("SharedMemoryParcelable mmap failed for fd = %d", mFd);
1135ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            return AAUDIO_ERROR_INTERNAL;
114204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        }
115204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
116204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    *regionAddressPtr = mResolvedAddress + offsetInBytes;
117c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    ALOGV("SharedMemoryParcelable mResolvedAddress = %p", mResolvedAddress);
118c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    ALOGV("SharedMemoryParcelable offset by %d, *regionAddressPtr = %p",
119204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk          offsetInBytes, *regionAddressPtr);
1205ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    return AAUDIO_OK;
121204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk}
122204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
123204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkint32_t SharedMemoryParcelable::getSizeInBytes() {
124204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    return mSizeInBytes;
125204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk}
126204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
1275ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t SharedMemoryParcelable::validate() {
1283df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk    if (mSizeInBytes < 0 || mSizeInBytes >= MAX_MMAP_SIZE_BYTES) {
129204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        ALOGE("SharedMemoryParcelable invalid mSizeInBytes = %d", mSizeInBytes);
1303df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk        return AAUDIO_ERROR_OUT_OF_RANGE;
131204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
132204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    if (mSizeInBytes > 0) {
133204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        if (mFd == -1) {
134204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            ALOGE("SharedMemoryParcelable uninitialized mFd = %d", mFd);
1355ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            return AAUDIO_ERROR_INTERNAL;
136204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        }
137204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
1385ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    return AAUDIO_OK;
139204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk}
140204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
141204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkvoid SharedMemoryParcelable::dump() {
142204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    ALOGD("SharedMemoryParcelable mFd = %d", mFd);
143204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    ALOGD("SharedMemoryParcelable mSizeInBytes = %d", mSizeInBytes);
144204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    ALOGD("SharedMemoryParcelable mResolvedAddress = %p", mResolvedAddress);
145204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk}
146