Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3738fe1b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Make mediaserver listen to Codec2 services' deaths" into qt-dev

parents 3208826f 270dd6a1
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -99,6 +99,7 @@ cc_library {
    export_shared_lib_headers: [
    export_shared_lib_headers: [
        "android.hardware.media.c2@1.0",
        "android.hardware.media.c2@1.0",
        "libcodec2",
        "libcodec2",
        "libcodec2_vndk",
        "libhidlbase",
        "libhidlbase",
        "libstagefright_bufferpool@2.0",
        "libstagefright_bufferpool@2.0",
        "libui",
        "libui",
+1 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ cc_library {
    export_shared_lib_headers: [
    export_shared_lib_headers: [
        "libcodec2",
        "libcodec2",
        "libcodec2_hidl_client@1.0",
        "libcodec2_hidl_client@1.0",
        "libcodec2_vndk",
    ],
    ],


}
}
+97 −91
Original line number Original line Diff line number Diff line
@@ -75,82 +75,11 @@ namespace /* unnamed */ {
// c2_status_t value that corresponds to hwbinder transaction failure.
// c2_status_t value that corresponds to hwbinder transaction failure.
constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;


// Returns the list of IComponentStore service names that are available on the
// Searches for a name in GetServiceNames() and returns the index found. If the
// device. This list is specified at the build time in manifest files.
// Note: A software service will have "_software" as a suffix.
std::vector<std::string> const& getServiceNames() {
    static std::vector<std::string> sServiceNames{[]() {
        using ::android::hardware::media::c2::V1_0::IComponentStore;
        using ::android::hidl::manager::V1_2::IServiceManager;

        while (true) {
            sp<IServiceManager> serviceManager = IServiceManager::getService();
            CHECK(serviceManager) << "Hardware service manager is not running.";

            // There are three categories of services based on names.
            std::vector<std::string> defaultNames; // Prefixed with "default"
            std::vector<std::string> vendorNames;  // Prefixed with "vendor"
            std::vector<std::string> otherNames;   // Others
            Return<void> transResult;
            transResult = serviceManager->listManifestByInterface(
                    IComponentStore::descriptor,
                    [&defaultNames, &vendorNames, &otherNames](
                            hidl_vec<hidl_string> const& instanceNames) {
                        for (hidl_string const& instanceName : instanceNames) {
                            char const* name = instanceName.c_str();
                            if (strncmp(name, "default", 7) == 0) {
                                defaultNames.emplace_back(name);
                            } else if (strncmp(name, "vendor", 6) == 0) {
                                vendorNames.emplace_back(name);
                            } else {
                                otherNames.emplace_back(name);
                            }
                        }
                    });
            if (transResult.isOk()) {
                // Sort service names in each category.
                std::sort(defaultNames.begin(), defaultNames.end());
                std::sort(vendorNames.begin(), vendorNames.end());
                std::sort(otherNames.begin(), otherNames.end());

                // Concatenate the three lists in this order: default, vendor,
                // other.
                std::vector<std::string>& names = defaultNames;
                names.reserve(names.size() + vendorNames.size() + otherNames.size());
                names.insert(names.end(),
                             std::make_move_iterator(vendorNames.begin()),
                             std::make_move_iterator(vendorNames.end()));
                names.insert(names.end(),
                             std::make_move_iterator(otherNames.begin()),
                             std::make_move_iterator(otherNames.end()));

                // Summarize to logcat.
                if (names.empty()) {
                    LOG(INFO) << "No Codec2 services declared in the manifest.";
                } else {
                    std::stringstream stringOutput;
                    stringOutput << "Available Codec2 services:";
                    for (std::string const& name : names) {
                        stringOutput << " \"" << name << "\"";
                    }
                    LOG(INFO) << stringOutput.str();
                }

                return names;
            }
            LOG(ERROR) << "Could not retrieve the list of service instances of "
                       << IComponentStore::descriptor
                       << ". Retrying...";
        }
    }()};
    return sServiceNames;
}

// Searches for a name in getServiceNames() and returns the index found. If the
// name is not found, the returned index will be equal to
// name is not found, the returned index will be equal to
// getServiceNames().size().
// GetServiceNames().size().
size_t getServiceIndex(char const* name) {
size_t getServiceIndex(char const* name) {
    std::vector<std::string> const& names = getServiceNames();
    std::vector<std::string> const& names = Codec2Client::GetServiceNames();
    size_t i = 0;
    size_t i = 0;
    for (; i < names.size(); ++i) {
    for (; i < names.size(); ++i) {
        if (name == names[i]) {
        if (name == names[i]) {
@@ -175,17 +104,14 @@ class Codec2Client::Cache {
    std::vector<C2Component::Traits> mTraits;
    std::vector<C2Component::Traits> mTraits;
    std::once_flag mTraitsInitializationFlag;
    std::once_flag mTraitsInitializationFlag;


    // The index of the service. This is based on getServiceNames().
    // The index of the service. This is based on GetServiceNames().
    size_t mIndex;
    size_t mIndex;
    // A "valid" cache object must have its mIndex set with init().
    bool mValid{false};
    // Called by s() exactly once to initialize the cache. The index must be a
    // Called by s() exactly once to initialize the cache. The index must be a
    // valid index into the vector returned by getServiceNames(). Calling
    // valid index into the vector returned by GetServiceNames(). Calling
    // init(index) will associate the cache to the service with name
    // init(index) will associate the cache to the service with name
    // getServiceNames()[index].
    // GetServiceNames()[index].
    void init(size_t index) {
    void init(size_t index) {
        mIndex = index;
        mIndex = index;
        mValid = true;
    }
    }


public:
public:
@@ -195,7 +121,6 @@ public:
    // If the service is unavailable but listed in the manifest, this function
    // If the service is unavailable but listed in the manifest, this function
    // will block indefinitely.
    // will block indefinitely.
    std::shared_ptr<Codec2Client> getClient() {
    std::shared_ptr<Codec2Client> getClient() {
        CHECK(mValid) << "Uninitialized cache";
        std::scoped_lock lock{mClientMutex};
        std::scoped_lock lock{mClientMutex};
        if (!mClient) {
        if (!mClient) {
            mClient = Codec2Client::_CreateFromIndex(mIndex);
            mClient = Codec2Client::_CreateFromIndex(mIndex);
@@ -208,7 +133,6 @@ public:
    //
    //
    // Note: This function is called only by ForAllServices().
    // Note: This function is called only by ForAllServices().
    void invalidate() {
    void invalidate() {
        CHECK(mValid) << "Uninitialized cache";
        std::scoped_lock lock{mClientMutex};
        std::scoped_lock lock{mClientMutex};
        mClient = nullptr;
        mClient = nullptr;
    }
    }
@@ -216,7 +140,6 @@ public:
    // Returns a list of traits for components supported by the service. This
    // Returns a list of traits for components supported by the service. This
    // list is cached.
    // list is cached.
    std::vector<C2Component::Traits> const& getTraits() {
    std::vector<C2Component::Traits> const& getTraits() {
        CHECK(mValid) << "Uninitialized cache";
        std::call_once(mTraitsInitializationFlag, [this]() {
        std::call_once(mTraitsInitializationFlag, [this]() {
            bool success{false};
            bool success{false};
            // Spin until _listComponents() is successful.
            // Spin until _listComponents() is successful.
@@ -229,7 +152,7 @@ public:
                using namespace std::chrono_literals;
                using namespace std::chrono_literals;
                static constexpr auto kServiceRetryPeriod = 5s;
                static constexpr auto kServiceRetryPeriod = 5s;
                LOG(INFO) << "Failed to retrieve component traits from service "
                LOG(INFO) << "Failed to retrieve component traits from service "
                             "\"" << getServiceNames()[mIndex] << "\". "
                             "\"" << GetServiceNames()[mIndex] << "\". "
                             "Retrying...";
                             "Retrying...";
                std::this_thread::sleep_for(kServiceRetryPeriod);
                std::this_thread::sleep_for(kServiceRetryPeriod);
            }
            }
@@ -240,7 +163,7 @@ public:
    // List() returns the list of all caches.
    // List() returns the list of all caches.
    static std::vector<Cache>& List() {
    static std::vector<Cache>& List() {
        static std::vector<Cache> sCaches{[]() {
        static std::vector<Cache> sCaches{[]() {
            size_t numServices = getServiceNames().size();
            size_t numServices = GetServiceNames().size();
            std::vector<Cache> caches(numServices);
            std::vector<Cache> caches(numServices);
            for (size_t i = 0; i < numServices; ++i) {
            for (size_t i = 0; i < numServices; ++i) {
                caches[i].init(i);
                caches[i].init(i);
@@ -610,8 +533,12 @@ Codec2Client::Codec2Client(const sp<IComponentStore>& base,
    }
    }
}
}


sp<Codec2Client::Base> const& Codec2Client::getBase() const {
    return mBase;
}

std::string const& Codec2Client::getServiceName() const {
std::string const& Codec2Client::getServiceName() const {
    return getServiceNames()[mServiceIndex];
    return GetServiceNames()[mServiceIndex];
}
}


c2_status_t Codec2Client::createComponent(
c2_status_t Codec2Client::createComponent(
@@ -807,15 +734,94 @@ std::shared_ptr<C2ParamReflector>
    return std::make_shared<SimpleParamReflector>(mBase);
    return std::make_shared<SimpleParamReflector>(mBase);
};
};


std::vector<std::string> const& Codec2Client::GetServiceNames() {
    static std::vector<std::string> sServiceNames{[]() {
        using ::android::hardware::media::c2::V1_0::IComponentStore;
        using ::android::hidl::manager::V1_2::IServiceManager;

        while (true) {
            sp<IServiceManager> serviceManager = IServiceManager::getService();
            CHECK(serviceManager) << "Hardware service manager is not running.";

            // There are three categories of services based on names.
            std::vector<std::string> defaultNames; // Prefixed with "default"
            std::vector<std::string> vendorNames;  // Prefixed with "vendor"
            std::vector<std::string> otherNames;   // Others
            Return<void> transResult;
            transResult = serviceManager->listManifestByInterface(
                    IComponentStore::descriptor,
                    [&defaultNames, &vendorNames, &otherNames](
                            hidl_vec<hidl_string> const& instanceNames) {
                        for (hidl_string const& instanceName : instanceNames) {
                            char const* name = instanceName.c_str();
                            if (strncmp(name, "default", 7) == 0) {
                                defaultNames.emplace_back(name);
                            } else if (strncmp(name, "vendor", 6) == 0) {
                                vendorNames.emplace_back(name);
                            } else {
                                otherNames.emplace_back(name);
                            }
                        }
                    });
            if (transResult.isOk()) {
                // Sort service names in each category.
                std::sort(defaultNames.begin(), defaultNames.end());
                std::sort(vendorNames.begin(), vendorNames.end());
                std::sort(otherNames.begin(), otherNames.end());

                // Concatenate the three lists in this order: default, vendor,
                // other.
                std::vector<std::string>& names = defaultNames;
                names.reserve(names.size() + vendorNames.size() + otherNames.size());
                names.insert(names.end(),
                             std::make_move_iterator(vendorNames.begin()),
                             std::make_move_iterator(vendorNames.end()));
                names.insert(names.end(),
                             std::make_move_iterator(otherNames.begin()),
                             std::make_move_iterator(otherNames.end()));

                // Summarize to logcat.
                if (names.empty()) {
                    LOG(INFO) << "No Codec2 services declared in the manifest.";
                } else {
                    std::stringstream stringOutput;
                    stringOutput << "Available Codec2 services:";
                    for (std::string const& name : names) {
                        stringOutput << " \"" << name << "\"";
                    }
                    LOG(INFO) << stringOutput.str();
                }

                return names;
            }
            LOG(ERROR) << "Could not retrieve the list of service instances of "
                       << IComponentStore::descriptor
                       << ". Retrying...";
        }
    }()};
    return sServiceNames;
}

std::shared_ptr<Codec2Client> Codec2Client::CreateFromService(
std::shared_ptr<Codec2Client> Codec2Client::CreateFromService(
        const char* name) {
        const char* name) {
    size_t index = getServiceIndex(name);
    size_t index = getServiceIndex(name);
    return index == getServiceNames().size() ?
    return index == GetServiceNames().size() ?
            nullptr : _CreateFromIndex(index);
            nullptr : _CreateFromIndex(index);
}
}


std::vector<std::shared_ptr<Codec2Client>> Codec2Client::
        CreateFromAllServices() {
    std::vector<std::shared_ptr<Codec2Client>> clients(
            GetServiceNames().size());
    for (size_t i = GetServiceNames().size(); i > 0; ) {
        --i;
        clients[i] = _CreateFromIndex(i);
    }
    return clients;
}

std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) {
std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) {
    std::string const& name = getServiceNames()[index];
    std::string const& name = GetServiceNames()[index];
    LOG(INFO) << "Creating a Codec2 client to service \"" << name << "\"";
    LOG(INFO) << "Creating a Codec2 client to service \"" << name << "\"";
    sp<Base> baseStore = Base::getService(name);
    sp<Base> baseStore = Base::getService(name);
    CHECK(baseStore) << "Codec2 service \"" << name << "\""
    CHECK(baseStore) << "Codec2 service \"" << name << "\""
@@ -958,17 +964,17 @@ std::shared_ptr<Codec2Client::InputSurface> Codec2Client::CreateInputSurface(
    if (inputSurfaceSetting == 0) {
    if (inputSurfaceSetting == 0) {
        return nullptr;
        return nullptr;
    }
    }
    size_t index = getServiceNames().size();
    size_t index = GetServiceNames().size();
    if (serviceName) {
    if (serviceName) {
        index = getServiceIndex(serviceName);
        index = getServiceIndex(serviceName);
        if (index == getServiceNames().size()) {
        if (index == GetServiceNames().size()) {
            LOG(DEBUG) << "CreateInputSurface -- invalid service name: \""
            LOG(DEBUG) << "CreateInputSurface -- invalid service name: \""
                       << serviceName << "\"";
                       << serviceName << "\"";
        }
        }
    }
    }


    std::shared_ptr<Codec2Client::InputSurface> inputSurface;
    std::shared_ptr<Codec2Client::InputSurface> inputSurface;
    if (index != getServiceNames().size()) {
    if (index != GetServiceNames().size()) {
        std::shared_ptr<Codec2Client> client = Cache::List()[index].getClient();
        std::shared_ptr<Codec2Client> client = Cache::List()[index].getClient();
        if (client->createInputSurface(&inputSurface) == C2_OK) {
        if (client->createInputSurface(&inputSurface) == C2_OK) {
            return inputSurface;
            return inputSurface;
+11 −0
Original line number Original line Diff line number Diff line
@@ -143,6 +143,8 @@ struct Codec2Client : public Codec2ConfigurableClient {


    typedef Codec2Client Store;
    typedef Codec2Client Store;


    sp<Base> const& getBase() const;

    std::string const& getServiceName() const;
    std::string const& getServiceName() const;


    c2_status_t createComponent(
    c2_status_t createComponent(
@@ -165,8 +167,17 @@ struct Codec2Client : public Codec2ConfigurableClient {


    std::shared_ptr<C2ParamReflector> getParamReflector();
    std::shared_ptr<C2ParamReflector> getParamReflector();


    // Returns the list of IComponentStore service names that are available on
    // the device. This list is specified at the build time in manifest files.
    // Note: A software service will have "_software" as a suffix.
    static std::vector<std::string> const& GetServiceNames();

    // Create a service with a given service name.
    static std::shared_ptr<Codec2Client> CreateFromService(char const* name);
    static std::shared_ptr<Codec2Client> CreateFromService(char const* name);


    // Get clients to all services.
    static std::vector<std::shared_ptr<Codec2Client>> CreateFromAllServices();

    // Try to create a component with a given name from all known
    // Try to create a component with a given name from all known
    // IComponentStore services.
    // IComponentStore services.
    static std::shared_ptr<Component> CreateComponentByName(
    static std::shared_ptr<Component> CreateComponentByName(
+2 −0
Original line number Original line Diff line number Diff line
@@ -2,6 +2,7 @@ cc_library_shared {


    srcs: [
    srcs: [
        "ActivityManager.cpp",
        "ActivityManager.cpp",
        "DeathNotifier.cpp",
        "MediaPlayerFactory.cpp",
        "MediaPlayerFactory.cpp",
        "MediaPlayerService.cpp",
        "MediaPlayerService.cpp",
        "MediaRecorderClient.cpp",
        "MediaRecorderClient.cpp",
@@ -17,6 +18,7 @@ cc_library_shared {
        "libaudioclient",
        "libaudioclient",
        "libbinder",
        "libbinder",
        "libcamera_client",
        "libcamera_client",
        "libcodec2_client",
        "libcrypto",
        "libcrypto",
        "libcutils",
        "libcutils",
        "libdl",
        "libdl",
Loading