1d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent/*
2d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent**
3d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** Copyright 2015, The Android Open Source Project
4d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent**
5d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** Licensed under the Apache License, Version 2.0 (the "License");
6d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** you may not use this file except in compliance with the License.
7d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** You may obtain a copy of the License at
8d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent**
9d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent**     http://www.apache.org/licenses/LICENSE-2.0
10d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent**
11d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** Unless required by applicable law or agreed to in writing, software
12d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** distributed under the License is distributed on an "AS IS" BASIS,
13d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** See the License for the specific language governing permissions and
15d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** limitations under the License.
16d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent*/
17d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
18d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#define LOG_TAG "IRadio"
19d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <utils/Log.h>
20d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <utils/Errors.h>
21d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <binder/IMemory.h>
22d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <radio/IRadio.h>
23d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <radio/IRadioService.h>
24d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <radio/IRadioClient.h>
25d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <system/radio.h>
26d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <system/radio_metadata.h>
27d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
28d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurentnamespace android {
29d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
30d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurentenum {
31d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    DETACH = IBinder::FIRST_CALL_TRANSACTION,
32d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    SET_CONFIGURATION,
33d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    GET_CONFIGURATION,
34d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    SET_MUTE,
35d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    GET_MUTE,
36d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    SCAN,
37d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    STEP,
38d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    TUNE,
39d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    CANCEL,
40d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    GET_PROGRAM_INFORMATION,
41d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    HAS_CONTROL
42d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent};
43d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
44d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurentclass BpRadio: public BpInterface<IRadio>
45d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent{
46d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurentpublic:
47d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    BpRadio(const sp<IBinder>& impl)
48d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        : BpInterface<IRadio>(impl)
49d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
50d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
51d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
52d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    void detach()
53d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
54d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        ALOGV("detach");
55d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        Parcel data, reply;
56d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
57d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        remote()->transact(DETACH, data, &reply);
58d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
59d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
60d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    virtual status_t setConfiguration(const struct radio_band_config *config)
61d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
62d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        Parcel data, reply;
63d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (config == NULL) {
64d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return BAD_VALUE;
65d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
66d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
67d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.write(config, sizeof(struct radio_band_config));
68d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        status_t status = remote()->transact(SET_CONFIGURATION, data, &reply);
69d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (status == NO_ERROR) {
70d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status = (status_t)reply.readInt32();
71d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
72d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        return status;
73d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
74d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
75d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    virtual status_t getConfiguration(struct radio_band_config *config)
76d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
77d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        Parcel data, reply;
78d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (config == NULL) {
79d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return BAD_VALUE;
80d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
81d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
82d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        status_t status = remote()->transact(GET_CONFIGURATION, data, &reply);
83d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (status == NO_ERROR) {
84d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status = (status_t)reply.readInt32();
85d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            if (status == NO_ERROR) {
86d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                reply.read(config, sizeof(struct radio_band_config));
87d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            }
88d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
89d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        return status;
90d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
91d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
92d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    virtual status_t setMute(bool mute)
93d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
94d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        Parcel data, reply;
95d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
96d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInt32(mute ? 1 : 0);
97d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        status_t status = remote()->transact(SET_MUTE, data, &reply);
98d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (status == NO_ERROR) {
99d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status = (status_t)reply.readInt32();
100d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
101d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        return status;
102d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
103d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
104d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    virtual status_t getMute(bool *mute)
105d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
106d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        Parcel data, reply;
107d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (mute == NULL) {
108d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return BAD_VALUE;
109d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
110d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
111d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        status_t status = remote()->transact(GET_MUTE, data, &reply);
112d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (status == NO_ERROR) {
113d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status = (status_t)reply.readInt32();
114d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            if (status == NO_ERROR) {
115d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                int muteread = reply.readInt32();
116d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                *mute = muteread != 0;
117d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            }
118d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
119d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        return status;
120d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
121d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
122d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    virtual status_t scan(radio_direction_t direction, bool skipSubChannel)
123d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
124d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        Parcel data, reply;
125d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
126d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInt32(direction);
127d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInt32(skipSubChannel ? 1 : 0);
128d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        status_t status = remote()->transact(SCAN, data, &reply);
129d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (status == NO_ERROR) {
130d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status = (status_t)reply.readInt32();
131d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
132d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        return status;
133d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
134d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
135d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    virtual status_t step(radio_direction_t direction, bool skipSubChannel)
136d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
137d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        Parcel data, reply;
138d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
139d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInt32(direction);
140d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInt32(skipSubChannel ? 1 : 0);
141d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        status_t status = remote()->transact(STEP, data, &reply);
142d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (status == NO_ERROR) {
143d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status = (status_t)reply.readInt32();
144d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
145d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        return status;
146d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
147d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
148d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    virtual status_t tune(unsigned int channel, unsigned int subChannel)
149d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
150d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        Parcel data, reply;
151d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
152d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInt32(channel);
153d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInt32(subChannel);
154d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        status_t status = remote()->transact(TUNE, data, &reply);
155d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (status == NO_ERROR) {
156d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status = (status_t)reply.readInt32();
157d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
158d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        return status;
159d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
160d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
161d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    virtual status_t cancel()
162d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
163d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        Parcel data, reply;
164d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
165d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        status_t status = remote()->transact(CANCEL, data, &reply);
166d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (status == NO_ERROR) {
167d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status = (status_t)reply.readInt32();
168d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
169d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        return status;
170d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
171d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
172d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    virtual status_t getProgramInformation(struct radio_program_info *info)
173d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
174d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        Parcel data, reply;
175d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (info == NULL) {
176d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return BAD_VALUE;
177d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
178d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        radio_metadata_t *metadata = info->metadata;
179d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
180d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        status_t status = remote()->transact(GET_PROGRAM_INFORMATION, data, &reply);
181d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (status == NO_ERROR) {
182d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status = (status_t)reply.readInt32();
183d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            if (status == NO_ERROR) {
184d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                reply.read(info, sizeof(struct radio_program_info));
185d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                info->metadata = metadata;
186d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                if (metadata == NULL) {
187d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                    return status;
188d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                }
189d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                size_t size = (size_t)reply.readInt32();
190d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                if (size == 0) {
191d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                    return status;
192d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                }
193d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                metadata =
194d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                    (radio_metadata_t *)calloc(size / sizeof(unsigned int), sizeof(unsigned int));
195d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                if (metadata == NULL) {
196d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                    return NO_MEMORY;
197d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                }
198d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                reply.read(metadata, size);
199d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                status = radio_metadata_add_metadata(&info->metadata, metadata);
200d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                free(metadata);
201d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            }
202d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
203d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        return status;
204d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
205d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
206d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    virtual status_t hasControl(bool *hasControl)
207d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    {
208d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        Parcel data, reply;
209d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (hasControl == NULL) {
210d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return BAD_VALUE;
211d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
212d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
213d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        status_t status = remote()->transact(HAS_CONTROL, data, &reply);
214d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        if (status == NO_ERROR) {
215d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status = (status_t)reply.readInt32();
216d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            if (status == NO_ERROR) {
217d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                *hasControl = reply.readInt32() != 0;
218d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            }
219d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
220d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        return status;
221d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
222d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent};
223d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
224d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric LaurentIMPLEMENT_META_INTERFACE(Radio, "android.hardware.IRadio");
225d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
226d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent// ----------------------------------------------------------------------
227d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
228d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurentstatus_t BnRadio::onTransact(
229d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
230d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent{
231d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    switch(code) {
232d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        case DETACH: {
233d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            ALOGV("DETACH");
234d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            CHECK_INTERFACE(IRadio, data, reply);
235d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            detach();
236d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return NO_ERROR;
237d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        } break;
238d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        case SET_CONFIGURATION: {
239d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            CHECK_INTERFACE(IRadio, data, reply);
240d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            struct radio_band_config config;
241d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            data.read(&config, sizeof(struct radio_band_config));
242d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status_t status = setConfiguration(&config);
243d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            reply->writeInt32(status);
244d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return NO_ERROR;
245d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
246d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        case GET_CONFIGURATION: {
247d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            CHECK_INTERFACE(IRadio, data, reply);
248d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            struct radio_band_config config;
249d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status_t status = getConfiguration(&config);
250d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            reply->writeInt32(status);
251d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            if (status == NO_ERROR) {
252d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                reply->write(&config, sizeof(struct radio_band_config));
253d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            }
254d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return NO_ERROR;
255d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
256d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        case SET_MUTE: {
257d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            CHECK_INTERFACE(IRadio, data, reply);
258d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            bool mute = data.readInt32() != 0;
259d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status_t status = setMute(mute);
260d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            reply->writeInt32(status);
261d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return NO_ERROR;
262d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
263d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        case GET_MUTE: {
264d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            CHECK_INTERFACE(IRadio, data, reply);
265d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            bool mute;
266d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status_t status = getMute(&mute);
267d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            reply->writeInt32(status);
268d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            if (status == NO_ERROR) {
269d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                reply->writeInt32(mute ? 1 : 0);
270d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            }
271d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return NO_ERROR;
272d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
273d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        case SCAN: {
274d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            CHECK_INTERFACE(IRadio, data, reply);
275d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            radio_direction_t direction = (radio_direction_t)data.readInt32();
276d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            bool skipSubChannel = data.readInt32() == 1;
277d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status_t status = scan(direction, skipSubChannel);
278d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            reply->writeInt32(status);
279d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return NO_ERROR;
280d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
281d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        case STEP: {
282d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            CHECK_INTERFACE(IRadio, data, reply);
283d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            radio_direction_t direction = (radio_direction_t)data.readInt32();
284d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            bool skipSubChannel = data.readInt32() == 1;
285d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status_t status = step(direction, skipSubChannel);
286d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            reply->writeInt32(status);
287d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return NO_ERROR;
288d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
289d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        case TUNE: {
290d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            CHECK_INTERFACE(IRadio, data, reply);
291d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            unsigned int channel = (unsigned int)data.readInt32();
292d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            unsigned int subChannel = (unsigned int)data.readInt32();
293d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status_t status = tune(channel, subChannel);
294d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            reply->writeInt32(status);
295d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return NO_ERROR;
296d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
297d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        case CANCEL: {
298d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            CHECK_INTERFACE(IRadio, data, reply);
299d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status_t status = cancel();
300d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            reply->writeInt32(status);
301d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return NO_ERROR;
302d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
303d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        case GET_PROGRAM_INFORMATION: {
304d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            CHECK_INTERFACE(IRadio, data, reply);
305d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            struct radio_program_info info;
306d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
307d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status_t status = radio_metadata_allocate(&info.metadata, 0, 0);
308d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            if (status != NO_ERROR) {
309d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                return status;
310d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            }
311d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status = getProgramInformation(&info);
312d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            reply->writeInt32(status);
313d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            if (status == NO_ERROR) {
314d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                reply->write(&info, sizeof(struct radio_program_info));
315d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                int count = radio_metadata_get_count(info.metadata);
316d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                if (count > 0) {
317d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                    size_t size = radio_metadata_get_size(info.metadata);
318d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                    reply->writeInt32(size);
319d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                    reply->write(info.metadata, size);
320d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                } else {
321d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                    reply->writeInt32(0);
322d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                }
323d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            }
324d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            radio_metadata_deallocate(info.metadata);
325d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return NO_ERROR;
326d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
327d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        case HAS_CONTROL: {
328d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            CHECK_INTERFACE(IRadio, data, reply);
329d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            bool control;
330d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            status_t status = hasControl(&control);
331d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            reply->writeInt32(status);
332d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            if (status == NO_ERROR) {
333d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent                reply->writeInt32(control ? 1 : 0);
334d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            }
335d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return NO_ERROR;
336d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        }
337d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent        default:
338d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent            return BBinder::onTransact(code, data, reply, flags);
339d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent    }
340d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent}
341d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
342d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent// ----------------------------------------------------------------------------
343d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent
344d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent}; // namespace android
345