1e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber/*
2e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber *
4e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * you may not use this file except in compliance with the License.
6e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * You may obtain a copy of the License at
7e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber *
8e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber *
10e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * Unless required by applicable law or agreed to in writing, software
11e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * See the License for the specific language governing permissions and
14e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * limitations under the License.
15e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber */
16e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
171629399bb578fc176613ccaf134d1be6e3047638Andreas Huber//#define LOG_NDEBUG 0
181629399bb578fc176613ccaf134d1be6e3047638Andreas Huber#define LOG_TAG "OMXMaster"
191629399bb578fc176613ccaf134d1be6e3047638Andreas Huber#include <utils/Log.h>
201629399bb578fc176613ccaf134d1be6e3047638Andreas Huber
21e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include "OMXMaster.h"
22e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
23bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "SoftOMXPlugin.h"
24bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
25e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include <dlfcn.h>
261900e77bac4276f247f80fd06d19316cac598f57Marco Nelissen#include <fcntl.h>
27e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
28f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
29e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
30e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Hubernamespace android {
31e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
32e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas HuberOMXMaster::OMXMaster()
33e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    : mVendorLibHandle(NULL) {
341900e77bac4276f247f80fd06d19316cac598f57Marco Nelissen
352c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV    pid_t pid = getpid();
362c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV    char filename[20];
372c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV    snprintf(filename, sizeof(filename), "/proc/%d/comm", pid);
382c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV    int fd = open(filename, O_RDONLY);
392c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV    if (fd < 0) {
402c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV      ALOGW("couldn't determine process name");
412c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV      strlcpy(mProcessName, "<unknown>", sizeof(mProcessName));
422c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV    } else {
432c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV      ssize_t len = read(fd, mProcessName, sizeof(mProcessName));
442c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV      if (len < 2) {
452c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV        ALOGW("couldn't determine process name");
462c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV        strlcpy(mProcessName, "<unknown>", sizeof(mProcessName));
472c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV      } else {
482c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV        // the name is newline terminated, so erase the newline
492c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV        mProcessName[len - 1] = 0;
502c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV      }
512c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV      close(fd);
521900e77bac4276f247f80fd06d19316cac598f57Marco Nelissen    }
531900e77bac4276f247f80fd06d19316cac598f57Marco Nelissen
54e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    addVendorPlugin();
55bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    addPlugin(new SoftOMXPlugin);
56e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
57e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
58e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas HuberOMXMaster::~OMXMaster() {
59e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    clearPlugins();
60e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
61e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    if (mVendorLibHandle != NULL) {
62e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        dlclose(mVendorLibHandle);
63e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        mVendorLibHandle = NULL;
64e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
65e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
66e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
67e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Hubervoid OMXMaster::addVendorPlugin() {
68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    addPlugin("libstagefrighthw.so");
69bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
70bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
71bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid OMXMaster::addPlugin(const char *libname) {
72bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    mVendorLibHandle = dlopen(libname, RTLD_NOW);
73e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
74e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    if (mVendorLibHandle == NULL) {
75e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        return;
76e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
77e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
78e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    typedef OMXPluginBase *(*CreateOMXPluginFunc)();
79e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    CreateOMXPluginFunc createOMXPlugin =
80e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        (CreateOMXPluginFunc)dlsym(
81673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev                mVendorLibHandle, "createOMXPlugin");
82673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev    if (!createOMXPlugin)
83673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev        createOMXPlugin = (CreateOMXPluginFunc)dlsym(
84e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber                mVendorLibHandle, "_ZN7android15createOMXPluginEv");
85e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
86f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    if (createOMXPlugin) {
87f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber        addPlugin((*createOMXPlugin)());
88f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    }
89e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
90e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
91e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Hubervoid OMXMaster::addPlugin(OMXPluginBase *plugin) {
92e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    Mutex::Autolock autoLock(mLock);
93e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
94e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    mPlugins.push_back(plugin);
95e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
96e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    OMX_U32 index = 0;
97e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
98e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    char name[128];
99e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    OMX_ERRORTYPE err;
100e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    while ((err = plugin->enumerateComponents(
101e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber                    name, sizeof(name), index++)) == OMX_ErrorNone) {
102e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        String8 name8(name);
103e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
104e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        if (mPluginByComponentName.indexOfKey(name8) >= 0) {
10529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("A component of name '%s' already exists, ignoring this one.",
106e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber                 name8.string());
107e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
108e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber            continue;
109e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        }
110e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
111e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        mPluginByComponentName.add(name8, plugin);
112e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
11381eacb8bbf331501bb68c7f1fdd7ca1811b03f8fAndreas Huber
11481eacb8bbf331501bb68c7f1fdd7ca1811b03f8fAndreas Huber    if (err != OMX_ErrorNoMore) {
115a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGE("OMX plugin failed w/ error 0x%08x after registering %zu "
11681eacb8bbf331501bb68c7f1fdd7ca1811b03f8fAndreas Huber             "components", err, mPluginByComponentName.size());
11781eacb8bbf331501bb68c7f1fdd7ca1811b03f8fAndreas Huber    }
118e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
119e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
120e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Hubervoid OMXMaster::clearPlugins() {
121e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    Mutex::Autolock autoLock(mLock);
122e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
123673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev    typedef void (*DestroyOMXPluginFunc)(OMXPluginBase*);
124673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev    DestroyOMXPluginFunc destroyOMXPlugin =
125673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev        (DestroyOMXPluginFunc)dlsym(
126673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev                mVendorLibHandle, "destroyOMXPlugin");
127673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev
128e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    mPluginByComponentName.clear();
129e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
130e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    for (List<OMXPluginBase *>::iterator it = mPlugins.begin();
131673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev            it != mPlugins.end(); ++it) {
132673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev        if (destroyOMXPlugin)
133673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev            destroyOMXPlugin(*it);
134673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev        else
135673aebfc7e6e8d38ad29a66d68c71ea8e9121eb1Iliyan Malchev            delete *it;
136e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        *it = NULL;
137e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
138e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
139e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    mPlugins.clear();
140e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
141e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
142e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas HuberOMX_ERRORTYPE OMXMaster::makeComponentInstance(
143e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        const char *name,
144e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        const OMX_CALLBACKTYPE *callbacks,
145e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        OMX_PTR appData,
146e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        OMX_COMPONENTTYPE **component) {
1471900e77bac4276f247f80fd06d19316cac598f57Marco Nelissen    ALOGI("makeComponentInstance(%s) in %s process", name, mProcessName);
148e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    Mutex::Autolock autoLock(mLock);
149e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
150e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    *component = NULL;
151e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
152e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    ssize_t index = mPluginByComponentName.indexOfKey(String8(name));
153e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
154e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    if (index < 0) {
155e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        return OMX_ErrorInvalidComponentName;
156e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
157e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
158e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    OMXPluginBase *plugin = mPluginByComponentName.valueAt(index);
159f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    OMX_ERRORTYPE err =
160f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber        plugin->makeComponentInstance(name, callbacks, appData, component);
161f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
162f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    if (err != OMX_ErrorNone) {
163f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber        return err;
164f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    }
165f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
166f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    mPluginByInstance.add(*component, plugin);
167f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
168f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    return err;
169f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber}
170f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
171f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas HuberOMX_ERRORTYPE OMXMaster::destroyComponentInstance(
172f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber        OMX_COMPONENTTYPE *component) {
173f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    Mutex::Autolock autoLock(mLock);
174f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
175f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    ssize_t index = mPluginByInstance.indexOfKey(component);
176f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
177f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    if (index < 0) {
178f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber        return OMX_ErrorBadParameter;
179f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    }
180f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
181f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    OMXPluginBase *plugin = mPluginByInstance.valueAt(index);
182f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    mPluginByInstance.removeItemsAt(index);
183f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
184f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    return plugin->destroyComponentInstance(component);
185e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
186e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
187e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas HuberOMX_ERRORTYPE OMXMaster::enumerateComponents(
188e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        OMX_STRING name,
189e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        size_t size,
190e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        OMX_U32 index) {
191e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    Mutex::Autolock autoLock(mLock);
192e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
193e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    size_t numComponents = mPluginByComponentName.size();
194e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
195e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    if (index >= numComponents) {
196e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        return OMX_ErrorNoMore;
197e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
198e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
199e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    const String8 &name8 = mPluginByComponentName.keyAt(index);
200e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
201e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    CHECK(size >= 1 + name8.size());
202e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    strcpy(name, name8.string());
203e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
204e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    return OMX_ErrorNone;
205e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
206e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
2078ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas HuberOMX_ERRORTYPE OMXMaster::getRolesOfComponent(
2088ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber        const char *name,
2098ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber        Vector<String8> *roles) {
2108ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    Mutex::Autolock autoLock(mLock);
2118ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber
2128ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    roles->clear();
2138ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber
2148ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    ssize_t index = mPluginByComponentName.indexOfKey(String8(name));
2158ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber
2168ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    if (index < 0) {
2178ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber        return OMX_ErrorInvalidComponentName;
2188ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    }
2198ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber
2208ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    OMXPluginBase *plugin = mPluginByComponentName.valueAt(index);
2218ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    return plugin->getRolesOfComponent(name, roles);
2228ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber}
2238ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber
224e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}  // namespace android
225