summaryrefslogtreecommitdiffstats
path: root/nexus/PropertyManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'nexus/PropertyManager.cpp')
-rw-r--r--nexus/PropertyManager.cpp249
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);
-}