Home | History | Annotate | Download | only in libmedia
      1 /*
      2 **
      3 ** Copyright 2007, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 #define LOG_TAG "IAudioTrack"
     19 //#define LOG_NDEBUG 0
     20 #include <utils/Log.h>
     21 
     22 #include <stdint.h>
     23 #include <sys/types.h>
     24 
     25 #include <binder/Parcel.h>
     26 
     27 #include <media/IAudioTrack.h>
     28 
     29 namespace android {
     30 
     31 enum {
     32     GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
     33     START,
     34     STOP,
     35     FLUSH,
     36     RESERVED, // was MUTE
     37     PAUSE,
     38     ATTACH_AUX_EFFECT,
     39     SET_PARAMETERS,
     40     GET_TIMESTAMP,
     41     SIGNAL,
     42 };
     43 
     44 class BpAudioTrack : public BpInterface<IAudioTrack>
     45 {
     46 public:
     47     BpAudioTrack(const sp<IBinder>& impl)
     48         : BpInterface<IAudioTrack>(impl)
     49     {
     50     }
     51 
     52     virtual sp<IMemory> getCblk() const
     53     {
     54         Parcel data, reply;
     55         sp<IMemory> cblk;
     56         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
     57         status_t status = remote()->transact(GET_CBLK, data, &reply);
     58         if (status == NO_ERROR) {
     59             cblk = interface_cast<IMemory>(reply.readStrongBinder());
     60             if (cblk != 0 && cblk->pointer() == NULL) {
     61                 cblk.clear();
     62             }
     63         }
     64         return cblk;
     65     }
     66 
     67     virtual status_t start()
     68     {
     69         Parcel data, reply;
     70         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
     71         status_t status = remote()->transact(START, data, &reply);
     72         if (status == NO_ERROR) {
     73             status = reply.readInt32();
     74         } else {
     75             ALOGW("start() error: %s", strerror(-status));
     76         }
     77         return status;
     78     }
     79 
     80     virtual void stop()
     81     {
     82         Parcel data, reply;
     83         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
     84         remote()->transact(STOP, data, &reply);
     85     }
     86 
     87     virtual void flush()
     88     {
     89         Parcel data, reply;
     90         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
     91         remote()->transact(FLUSH, data, &reply);
     92     }
     93 
     94     virtual void pause()
     95     {
     96         Parcel data, reply;
     97         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
     98         remote()->transact(PAUSE, data, &reply);
     99     }
    100 
    101     virtual status_t attachAuxEffect(int effectId)
    102     {
    103         Parcel data, reply;
    104         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
    105         data.writeInt32(effectId);
    106         status_t status = remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
    107         if (status == NO_ERROR) {
    108             status = reply.readInt32();
    109         } else {
    110             ALOGW("attachAuxEffect() error: %s", strerror(-status));
    111         }
    112         return status;
    113     }
    114 
    115     virtual status_t setParameters(const String8& keyValuePairs) {
    116         Parcel data, reply;
    117         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
    118         data.writeString8(keyValuePairs);
    119         status_t status = remote()->transact(SET_PARAMETERS, data, &reply);
    120         if (status == NO_ERROR) {
    121             status = reply.readInt32();
    122         }
    123         return status;
    124     }
    125 
    126     virtual status_t getTimestamp(AudioTimestamp& timestamp) {
    127         Parcel data, reply;
    128         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
    129         status_t status = remote()->transact(GET_TIMESTAMP, data, &reply);
    130         if (status == NO_ERROR) {
    131             status = reply.readInt32();
    132             if (status == NO_ERROR) {
    133                 timestamp.mPosition = reply.readInt32();
    134                 timestamp.mTime.tv_sec = reply.readInt32();
    135                 timestamp.mTime.tv_nsec = reply.readInt32();
    136             }
    137         }
    138         return status;
    139     }
    140 
    141     virtual void signal() {
    142         Parcel data, reply;
    143         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
    144         remote()->transact(SIGNAL, data, &reply);
    145     }
    146 };
    147 
    148 IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
    149 
    150 // ----------------------------------------------------------------------
    151 
    152 status_t BnAudioTrack::onTransact(
    153     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    154 {
    155     switch (code) {
    156         case GET_CBLK: {
    157             CHECK_INTERFACE(IAudioTrack, data, reply);
    158             reply->writeStrongBinder(IInterface::asBinder(getCblk()));
    159             return NO_ERROR;
    160         } break;
    161         case START: {
    162             CHECK_INTERFACE(IAudioTrack, data, reply);
    163             reply->writeInt32(start());
    164             return NO_ERROR;
    165         } break;
    166         case STOP: {
    167             CHECK_INTERFACE(IAudioTrack, data, reply);
    168             stop();
    169             return NO_ERROR;
    170         } break;
    171         case FLUSH: {
    172             CHECK_INTERFACE(IAudioTrack, data, reply);
    173             flush();
    174             return NO_ERROR;
    175         } break;
    176         case PAUSE: {
    177             CHECK_INTERFACE(IAudioTrack, data, reply);
    178             pause();
    179             return NO_ERROR;
    180         }
    181         case ATTACH_AUX_EFFECT: {
    182             CHECK_INTERFACE(IAudioTrack, data, reply);
    183             reply->writeInt32(attachAuxEffect(data.readInt32()));
    184             return NO_ERROR;
    185         } break;
    186         case SET_PARAMETERS: {
    187             CHECK_INTERFACE(IAudioTrack, data, reply);
    188             String8 keyValuePairs(data.readString8());
    189             reply->writeInt32(setParameters(keyValuePairs));
    190             return NO_ERROR;
    191         } break;
    192         case GET_TIMESTAMP: {
    193             CHECK_INTERFACE(IAudioTrack, data, reply);
    194             AudioTimestamp timestamp;
    195             status_t status = getTimestamp(timestamp);
    196             reply->writeInt32(status);
    197             if (status == NO_ERROR) {
    198                 reply->writeInt32(timestamp.mPosition);
    199                 reply->writeInt32(timestamp.mTime.tv_sec);
    200                 reply->writeInt32(timestamp.mTime.tv_nsec);
    201             }
    202             return NO_ERROR;
    203         } break;
    204         case SIGNAL: {
    205             CHECK_INTERFACE(IAudioTrack, data, reply);
    206             signal();
    207             return NO_ERROR;
    208         } break;
    209         default:
    210             return BBinder::onTransact(code, data, reply, flags);
    211     }
    212 }
    213 
    214 } // namespace android
    215