1 /*
2 **
3 ** Copyright 2015, 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_NDEBUG 0
19 #define LOG_TAG "IResourceManagerService"
20 #include <utils/Log.h>
21 
22 #include <media/IResourceManagerService.h>
23 
24 #include <binder/Parcel.h>
25 
26 #include <stdint.h>
27 #include <sys/types.h>
28 
29 namespace android {
30 
31 enum {
32     CONFIG = IBinder::FIRST_CALL_TRANSACTION,
33     ADD_RESOURCE,
34     REMOVE_RESOURCE,
35     RECLAIM_RESOURCE,
36 };
37 
38 template <typename T>
writeToParcel(Parcel * data,const Vector<T> & items)39 static void writeToParcel(Parcel *data, const Vector<T> &items) {
40     size_t size = items.size();
41     // truncates size, but should be okay for this usecase
42     data->writeUint32(static_cast<uint32_t>(size));
43     for (size_t i = 0; i < size; i++) {
44         items[i].writeToParcel(data);
45     }
46 }
47 
48 template <typename T>
readFromParcel(const Parcel & data,Vector<T> * items)49 static void readFromParcel(const Parcel &data, Vector<T> *items) {
50     size_t size = (size_t)data.readUint32();
51     for (size_t i = 0; i < size && data.dataAvail() > 0; i++) {
52         T item;
53         item.readFromParcel(data);
54         items->add(item);
55     }
56 }
57 
58 class BpResourceManagerService : public BpInterface<IResourceManagerService>
59 {
60 public:
BpResourceManagerService(const sp<IBinder> & impl)61     explicit BpResourceManagerService(const sp<IBinder> &impl)
62         : BpInterface<IResourceManagerService>(impl)
63     {
64     }
65 
config(const Vector<MediaResourcePolicy> & policies)66     virtual void config(const Vector<MediaResourcePolicy> &policies) {
67         Parcel data, reply;
68         data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
69         writeToParcel(&data, policies);
70         remote()->transact(CONFIG, data, &reply);
71     }
72 
addResource(int pid,int64_t clientId,const sp<IResourceManagerClient> client,const Vector<MediaResource> & resources)73     virtual void addResource(
74             int pid,
75             int64_t clientId,
76             const sp<IResourceManagerClient> client,
77             const Vector<MediaResource> &resources) {
78         Parcel data, reply;
79         data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
80         data.writeInt32(pid);
81         data.writeInt64(clientId);
82         data.writeStrongBinder(IInterface::asBinder(client));
83         writeToParcel(&data, resources);
84 
85         remote()->transact(ADD_RESOURCE, data, &reply);
86     }
87 
removeResource(int pid,int64_t clientId)88     virtual void removeResource(int pid, int64_t clientId) {
89         Parcel data, reply;
90         data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
91         data.writeInt32(pid);
92         data.writeInt64(clientId);
93 
94         remote()->transact(REMOVE_RESOURCE, data, &reply);
95     }
96 
reclaimResource(int callingPid,const Vector<MediaResource> & resources)97     virtual bool reclaimResource(int callingPid, const Vector<MediaResource> &resources) {
98         Parcel data, reply;
99         data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
100         data.writeInt32(callingPid);
101         writeToParcel(&data, resources);
102 
103         bool ret = false;
104         status_t status = remote()->transact(RECLAIM_RESOURCE, data, &reply);
105         if (status == NO_ERROR) {
106             ret = (bool)reply.readInt32();
107         }
108         return ret;
109     }
110 };
111 
112 IMPLEMENT_META_INTERFACE(ResourceManagerService, "android.media.IResourceManagerService");
113 
114 // ----------------------------------------------------------------------
115 
116 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)117 status_t BnResourceManagerService::onTransact(
118     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags)
119 {
120     switch (code) {
121         case CONFIG: {
122             CHECK_INTERFACE(IResourceManagerService, data, reply);
123             Vector<MediaResourcePolicy> policies;
124             readFromParcel(data, &policies);
125             config(policies);
126             return NO_ERROR;
127         } break;
128 
129         case ADD_RESOURCE: {
130             CHECK_INTERFACE(IResourceManagerService, data, reply);
131             int pid = data.readInt32();
132             int64_t clientId = data.readInt64();
133             sp<IResourceManagerClient> client(
134                     interface_cast<IResourceManagerClient>(data.readStrongBinder()));
135             if (client == NULL) {
136                 return NO_ERROR;
137             }
138             Vector<MediaResource> resources;
139             readFromParcel(data, &resources);
140             addResource(pid, clientId, client, resources);
141             return NO_ERROR;
142         } break;
143 
144         case REMOVE_RESOURCE: {
145             CHECK_INTERFACE(IResourceManagerService, data, reply);
146             int pid = data.readInt32();
147             int64_t clientId = data.readInt64();
148             removeResource(pid, clientId);
149             return NO_ERROR;
150         } break;
151 
152         case RECLAIM_RESOURCE: {
153             CHECK_INTERFACE(IResourceManagerService, data, reply);
154             int callingPid = data.readInt32();
155             Vector<MediaResource> resources;
156             readFromParcel(data, &resources);
157             bool ret = reclaimResource(callingPid, resources);
158             reply->writeInt32(ret);
159             return NO_ERROR;
160         } break;
161 
162         default:
163             return BBinder::onTransact(code, data, reply, flags);
164     }
165 }
166 
167 // ----------------------------------------------------------------------------
168 
169 }; // namespace android
170