diff options
Diffstat (limited to 'nexus/PropertyManager.cpp')
-rw-r--r-- | nexus/PropertyManager.cpp | 249 |
1 files changed, 203 insertions, 46 deletions
diff --git a/nexus/PropertyManager.cpp b/nexus/PropertyManager.cpp index 6faf9b830..704b2230b 100644 --- a/nexus/PropertyManager.cpp +++ b/nexus/PropertyManager.cpp @@ -14,6 +14,11 @@ * limitations under the License. */ +#include <stdlib.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + #define LOG_TAG "PropertyManager" #include <cutils/log.h> @@ -21,103 +26,255 @@ #include "PropertyManager.h" PropertyManager::PropertyManager() { - mPropertyPairs = new PropertyPairCollection(); + mNamespaces = new PropertyNamespaceCollection(); pthread_mutex_init(&mLock, NULL); } PropertyManager::~PropertyManager() { - delete mPropertyPairs; + PropertyNamespaceCollection::iterator it; + + for (it = mNamespaces->begin(); it != mNamespaces->end();) { + delete (*it); + it = mNamespaces->erase(it); + } + delete mNamespaces; +} + +PropertyNamespace *PropertyManager::lookupNamespace_UNLOCKED(const char *ns) { + PropertyNamespaceCollection::iterator ns_it; + + for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) { + if (!strcasecmp(ns, (*ns_it)->getName())) + return (*ns_it); + } + errno = ENOENT; + return NULL; } -int PropertyManager::registerProperty(const char *name, IPropertyProvider *pp) { - PropertyPairCollection::iterator it; +Property *PropertyManager::lookupProperty_UNLOCKED(PropertyNamespace *ns, const char *name) { + PropertyCollection::iterator it; -// LOGD("registerProperty(%s)", name); + for (it = ns->getProperties()->begin(); + it != ns->getProperties()->end(); ++it) { + if (!strcasecmp(name, (*it)->getName())) + return (*it); + } + errno = ENOENT; + return NULL; +} + +int PropertyManager::attachProperty(const char *ns_name, Property *p) { + PropertyNamespace *ns; + + LOGD("Attaching property %s to namespace %s", p->getName(), ns_name); pthread_mutex_lock(&mLock); - for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) { - if (!strcmp(name, (*it)->getName())) { - errno = EADDRINUSE; - LOGE("Failed to register property %s (%s)", - name, strerror(errno)); - pthread_mutex_unlock(&mLock); - return -1; - } + if (!(ns = lookupNamespace_UNLOCKED(ns_name))) { + LOGD("Creating namespace %s", ns_name); + ns = new PropertyNamespace(ns_name); + mNamespaces->push_back(ns); + } + + if (lookupProperty_UNLOCKED(ns, p->getName())) { + errno = EADDRINUSE; + pthread_mutex_unlock(&mLock); + LOGE("Failed to register property %s.%s (%s)", + ns_name, p->getName(), strerror(errno)); + return -1; } - mPropertyPairs->push_back(new PropertyPair(name, pp)); + + ns->getProperties()->push_back(p); pthread_mutex_unlock(&mLock); return 0; } -int PropertyManager::unregisterProperty(const char *name) { - PropertyPairCollection::iterator it; +int PropertyManager::detachProperty(const char *ns_name, Property *p) { + PropertyNamespace *ns; -// LOGD("unregisterProperty(%s)", name); + LOGD("Detaching property %s from namespace %s", p->getName(), ns_name); pthread_mutex_lock(&mLock); - for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) { - if (!strcmp(name, (*it)->getName())) { + if (!(ns = lookupNamespace_UNLOCKED(ns_name))) { + pthread_mutex_unlock(&mLock); + LOGE("Namespace '%s' not found", ns_name); + return -1; + } + + PropertyCollection::iterator it; + + for (it = ns->getProperties()->begin(); + it != ns->getProperties()->end(); ++it) { + if (!strcasecmp(p->getName(), (*it)->getName())) { delete ((*it)); - mPropertyPairs->erase(it); + ns->getProperties()->erase(it); pthread_mutex_unlock(&mLock); return 0; } } + + LOGE("Property %s.%s not found", ns_name, p->getName()); pthread_mutex_unlock(&mLock); errno = ENOENT; return -1; } +int PropertyManager::doSet(Property *p, int idx, const char *value) { + + if (p->getReadOnly()) { + errno = EROFS; + return -1; + } + + if (p->getType() == Property::Type_STRING) { + return p->set(idx, value); + } else if (p->getType() == Property::Type_INTEGER) { + int tmp; + errno = 0; + tmp = strtol(value, (char **) NULL, 10); + if (errno) { + LOGE("Failed to convert '%s' to int", value); + errno = EINVAL; + return -1; + } + return p->set(idx, tmp); + } else if (p->getType() == Property::Type_IPV4) { + struct in_addr tmp; + if (!inet_aton(value, &tmp)) { + LOGE("Failed to convert '%s' to ipv4", value); + errno = EINVAL; + return -1; + } + return p->set(idx, &tmp); + } else { + LOGE("Property '%s' has an unknown type (%d)", p->getName(), + p->getType()); + errno = EINVAL; + return -1; + } + errno = ENOENT; + return -1; +} + +int PropertyManager::doGet(Property *p, int idx, char *buffer, size_t max) { + + if (p->getType() == Property::Type_STRING) { + if (p->get(idx, buffer, max)) { + LOGW("String property %s get failed (%s)", p->getName(), + strerror(errno)); + return -1; + } + } + else if (p->getType() == Property::Type_INTEGER) { + int tmp; + if (p->get(idx, &tmp)) { + LOGW("Integer property %s get failed (%s)", p->getName(), + strerror(errno)); + return -1; + } + snprintf(buffer, max, "%d", tmp); + } else if (p->getType() == Property::Type_IPV4) { + struct in_addr tmp; + if (p->get(idx, &tmp)) { + LOGW("IPV4 property %s get failed (%s)", p->getName(), + strerror(errno)); + return -1; + } + strncpy(buffer, inet_ntoa(tmp), max); + } else { + LOGE("Property '%s' has an unknown type (%d)", p->getName(), + p->getType()); + errno = EINVAL; + return -1; + } + return 0; +} + /* * IPropertyManager methods */ int PropertyManager::set(const char *name, const char *value) { - PropertyPairCollection::iterator it; + LOGD("set %s = '%s'", name, value); pthread_mutex_lock(&mLock); - for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) { - if (!strcmp(name, (*it)->getName())) { - pthread_mutex_unlock(&mLock); - return (*it)->getProvider()->set(name, value); + PropertyNamespaceCollection::iterator ns_it; + for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) { + PropertyCollection::iterator p_it; + for (p_it = (*ns_it)->getProperties()->begin(); + p_it != (*ns_it)->getProperties()->end(); ++p_it) { + for (int i = 0; i < (*p_it)->getNumElements(); i++) { + char fqn[255]; + char tmp[8]; + sprintf(tmp, "_%d", i); + snprintf(fqn, sizeof(fqn), "%s.%s%s", + (*ns_it)->getName(), (*p_it)->getName(), + ((*p_it)->getNumElements() > 1 ? tmp : "")); + if (!strcasecmp(name, fqn)) { + pthread_mutex_unlock(&mLock); + return doSet((*p_it), i, value); + } + } } } + + LOGE("Property %s not found", name); pthread_mutex_unlock(&mLock); errno = ENOENT; return -1; } const char *PropertyManager::get(const char *name, char *buffer, size_t max) { - PropertyPairCollection::iterator it; - - memset(buffer, 0, max); pthread_mutex_lock(&mLock); - for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) { - if (!strcmp(name, (*it)->getName())) { - pthread_mutex_unlock(&mLock); - return (*it)->getProvider()->get(name, buffer, max); + PropertyNamespaceCollection::iterator ns_it; + for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) { + PropertyCollection::iterator p_it; + for (p_it = (*ns_it)->getProperties()->begin(); + p_it != (*ns_it)->getProperties()->end(); ++p_it) { + + for (int i = 0; i < (*p_it)->getNumElements(); i++) { + char fqn[255]; + char tmp[8]; + sprintf(tmp, "_%d", i); + snprintf(fqn, sizeof(fqn), "%s.%s%s", + (*ns_it)->getName(), (*p_it)->getName(), + ((*p_it)->getNumElements() > 1 ? tmp : "")); + if (!strcasecmp(name, fqn)) { + pthread_mutex_unlock(&mLock); + if (doGet((*p_it), i, buffer, max)) + return NULL; + return buffer; + } } + } } + + LOGE("Property %s not found", name); pthread_mutex_unlock(&mLock); errno = ENOENT; return NULL; } -android::List<char *> *PropertyManager::createPropertyList() { +android::List<char *> *PropertyManager::createPropertyList(const char *prefix) { android::List<char *> *c = new android::List<char *>(); - PropertyPairCollection::iterator it; - pthread_mutex_lock(&mLock); - for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) - c->push_back(strdup((*it)->getName())); + PropertyNamespaceCollection::iterator ns_it; + for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) { + PropertyCollection::iterator p_it; + for (p_it = (*ns_it)->getProperties()->begin(); + p_it != (*ns_it)->getProperties()->end(); ++p_it) { + for (int i = 0; i < (*p_it)->getNumElements(); i++) { + char fqn[255]; + char tmp[8]; + sprintf(tmp, "_%d", i); + snprintf(fqn, sizeof(fqn), "%s.%s%s", + (*ns_it)->getName(), (*p_it)->getName(), + ((*p_it)->getNumElements() > 1 ? tmp : "")); + if (!prefix || + (prefix && !strncasecmp(fqn, prefix, strlen(prefix)))) { + c->push_back(strdup(fqn)); + } + } + } + } pthread_mutex_unlock(&mLock); return c; } - -PropertyPair::PropertyPair(const char *name, IPropertyProvider *pp) { - mName = strdup(name); - mPp = pp; -} - -PropertyPair::~PropertyPair() { - free(mName); -} |