Home | History | Annotate | Download | only in libmedia
      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>
     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>
     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:
     61     explicit BpResourceManagerService(const sp<IBinder> &impl)
     62         : BpInterface<IResourceManagerService>(impl)
     63     {
     64     }
     65 
     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 
     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 
     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 
     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 
    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