lr: add support for location resolver disable commands

This commit is contained in:
Michael Scire 2022-10-11 10:47:40 -07:00 committed by SciresM
parent 05de5538d6
commit e1aff401ba
12 changed files with 110 additions and 10 deletions

View file

@ -32,6 +32,9 @@ namespace ams::lr {
/* Use a redirection if present. */
R_SUCCEED_IF(m_program_redirector.FindRedirection(out.GetPointer(), id));
/* If we're not enabled, we can't resolve a program. */
R_UNLESS(m_enabled, lr::ResultProgramNotFound())
/* Find the latest program content for the program id. */
ncm::ContentId program_content_id;
R_TRY_CATCH(m_content_meta_database.GetLatestProgram(std::addressof(program_content_id), id)) {
@ -60,6 +63,9 @@ namespace ams::lr {
}
Result ContentLocationResolverImpl::ResolveDataPath(sf::Out<Path> out, ncm::DataId id) {
/* If we're not enabled, we can't resolve data. */
R_UNLESS(m_enabled, lr::ResultDataNotFound())
/* Find the latest data content for the program id. */
ncm::ContentId data_content_id;
R_TRY(m_content_meta_database.GetLatestData(std::addressof(data_content_id), id));
@ -166,9 +172,12 @@ namespace ams::lr {
/* Use a redirection if present. */
R_SUCCEED_IF(m_debug_program_redirector.FindRedirection(out.GetPointer(), id));
/* If we're not enabled, we can't resolve a program. */
R_UNLESS(m_enabled, lr::ResultDebugProgramNotFound())
/* Otherwise find the path for the program id. */
R_TRY_CATCH(this->ResolveProgramPath(out.GetPointer(), id)) {
R_CONVERT(ResultProgramNotFound, lr::ResultDebugProgramNotFound())
R_CONVERT(lr::ResultProgramNotFound, lr::ResultDebugProgramNotFound())
} R_END_TRY_CATCH;
R_SUCCEED();
@ -194,4 +203,9 @@ namespace ams::lr {
R_SUCCEED();
}
Result ContentLocationResolverImpl::Disable() {
m_enabled = false;
R_SUCCEED();
}
}

View file

@ -22,12 +22,13 @@ namespace ams::lr {
class ContentLocationResolverImpl : public LocationResolverImplBase {
private:
ncm::StorageId m_storage_id;
bool m_enabled;
/* Objects for this storage type. */
ncm::ContentMetaDatabase m_content_meta_database;
ncm::ContentStorage m_content_storage;
public:
ContentLocationResolverImpl(ncm::StorageId storage_id) : m_storage_id(storage_id), m_content_meta_database(), m_content_storage() { /* ... */ }
ContentLocationResolverImpl(ncm::StorageId storage_id, bool enabled) : m_storage_id(storage_id), m_enabled(enabled), m_content_meta_database(), m_content_storage() { /* ... */ }
~ContentLocationResolverImpl();
private:
@ -61,6 +62,7 @@ namespace ams::lr {
Result RedirectApplicationProgramPathForDebugDeprecated(const Path &path, ncm::ProgramId id);
Result RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id);
Result EraseProgramRedirectionForDebug(ncm::ProgramId id);
Result Disable();
};
static_assert(lr::IsILocationResolver<ContentLocationResolverImpl>);

View file

@ -27,10 +27,19 @@ namespace ams::lr {
using ContentLocationResolverFactory = sf::ObjectFactory<sf::StdAllocationPolicy<std::allocator>>;
using RedirectOnlyLocationResolverFactory = sf::ObjectFactory<sf::StdAllocationPolicy<std::allocator>>;
bool IsAcceptableStorageId(ncm::StorageId storage_id) {
if (ncm::IsInstallableStorage(storage_id)) {
return storage_id != ncm::StorageId::Any;
} else {
return storage_id == ncm::StorageId::Host || storage_id == ncm::StorageId::GameCard;
}
}
}
Result LocationResolverManagerImpl::OpenLocationResolver(sf::Out<sf::SharedPointer<ILocationResolver>> out, ncm::StorageId storage_id) {
std::scoped_lock lk(m_mutex);
/* Find an existing resolver. */
auto resolver = m_location_resolvers.Find(storage_id);
@ -39,7 +48,11 @@ namespace ams::lr {
if (storage_id == ncm::StorageId::Host) {
AMS_ABORT_UNLESS(m_location_resolvers.Insert(storage_id, RedirectOnlyLocationResolverFactory::CreateSharedEmplaced<ILocationResolver, RedirectOnlyLocationResolverImpl>()));
} else {
auto content_resolver = ContentLocationResolverFactory::CreateSharedEmplaced<ILocationResolver, ContentLocationResolverImpl>(storage_id);
/* Get enabled. */
auto *enabled = m_location_resolvers_enabled.Find(storage_id);
/* Create the resolver. */
auto content_resolver = ContentLocationResolverFactory::CreateSharedEmplaced<ILocationResolver, ContentLocationResolverImpl>(storage_id, enabled != nullptr ? *enabled : m_default_enabled);
R_TRY(content_resolver->Refresh());
AMS_ABORT_UNLESS(m_location_resolvers.Insert(storage_id, std::move(content_resolver)));
}
@ -94,4 +107,39 @@ namespace ams::lr {
R_SUCCEED();
}
Result LocationResolverManagerImpl::SetEnabled(const sf::InMapAliasArray<ncm::StorageId> &storages) {
std::scoped_lock lk(m_mutex);
/* If we're setting enabled, we're no longer enabled by default. */
m_default_enabled = false;
/* Create entries for each storage. */
for (size_t i = 0; i < storages.GetSize(); ++i) {
/* Get the storage id. */
const auto storage_id = storages[i];
/* Check that the storage id is acceptable. */
R_UNLESS(IsAcceptableStorageId(storage_id), lr::ResultUnknownStorageId());
/* Set the storage id as enabled. */
AMS_ABORT_UNLESS(m_location_resolvers_enabled.InsertOrAssign(storage_id, true));
}
/* Disable any open storages which shouldn't be enabled. */
m_location_resolvers.ForEach([&](ncm::StorageId storage_id, sf::SharedPointer<ILocationResolver> &resolver) -> void {
/* Check if the storage id is contained in the input array. */
for (size_t i = 0; i < storages.GetSize(); ++i) {
if (storages[i] == storage_id) {
/* The storage is enabled, so we can return. */
return;
}
}
/* The storage isn't enabled, so disable it. */
R_ABORT_UNLESS(resolver->Disable());
});
R_SUCCEED();
}
}

View file

@ -158,4 +158,8 @@ namespace ams::lr {
R_SUCCEED();
}
Result RedirectOnlyLocationResolverImpl::Disable() {
R_SUCCEED();
}
}

View file

@ -50,6 +50,7 @@ namespace ams::lr {
Result RedirectApplicationProgramPathForDebugDeprecated(const Path &path, ncm::ProgramId id);
Result RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id);
Result EraseProgramRedirectionForDebug(ncm::ProgramId id);
Result Disable();
};
static_assert(lr::IsILocationResolver<RedirectOnlyLocationResolverImpl>);

View file

@ -154,6 +154,11 @@ namespace ams::lr {
AMS_UNUSED(id);
AMS_ABORT();
}
Result Disable() {
/* TODO: libnx bindings */
AMS_ABORT();
}
};
static_assert(lr::IsILocationResolver<RemoteLocationResolverImpl>);
#endif

View file

@ -54,6 +54,11 @@ namespace ams::lr {
AMS_UNUSED(out);
AMS_ABORT("TODO: libnx binding");
}
Result SetEnabled(const sf::InMapAliasArray<ncm::StorageId> &storages) {
AMS_UNUSED(storages);
AMS_ABORT("TODO: libnx binding");
}
};
static_assert(lr::IsILocationResolverManager<RemoteLocationResolverManagerImpl>);
#endif