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