summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/MediaScanner.cpp148
-rw-r--r--media/libmedia/MediaScannerClient.cpp6
2 files changed, 82 insertions, 72 deletions
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index 45bdff4..41f8593 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -47,16 +47,15 @@ const char *MediaScanner::locale() const {
return mLocale;
}
-status_t MediaScanner::processDirectory(
- const char *path, MediaScannerClient &client,
- ExceptionCheck exceptionCheck, void *exceptionEnv) {
+MediaScanResult MediaScanner::processDirectory(
+ const char *path, MediaScannerClient &client) {
int pathLength = strlen(path);
if (pathLength >= PATH_MAX) {
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
char* pathBuffer = (char *)malloc(PATH_MAX + 1);
if (!pathBuffer) {
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_ERROR;
}
int pathRemaining = PATH_MAX - pathLength;
@@ -69,21 +68,18 @@ status_t MediaScanner::processDirectory(
client.setLocale(locale());
- status_t result =
- doProcessDirectory(pathBuffer, pathRemaining, client, false, exceptionCheck, exceptionEnv);
+ MediaScanResult result = doProcessDirectory(pathBuffer, pathRemaining, client, false);
free(pathBuffer);
return result;
}
-status_t MediaScanner::doProcessDirectory(
- char *path, int pathRemaining, MediaScannerClient &client,
- bool noMedia, ExceptionCheck exceptionCheck, void *exceptionEnv) {
+MediaScanResult MediaScanner::doProcessDirectory(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia) {
// place to copy file or directory name
char* fileSpot = path + strlen(path);
struct dirent* entry;
- struct stat statbuf;
// Treat all files as non-media in directories that contain a ".nomedia" file
if (pathRemaining >= 8 /* strlen(".nomedia") */ ) {
@@ -99,76 +95,88 @@ status_t MediaScanner::doProcessDirectory(
DIR* dir = opendir(path);
if (!dir) {
- LOGD("opendir %s failed, errno: %d", path, errno);
- return UNKNOWN_ERROR;
+ LOGW("Error opening directory '%s', skipping: %s.", path, strerror(errno));
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
+ MediaScanResult result = MEDIA_SCAN_RESULT_OK;
while ((entry = readdir(dir))) {
- const char* name = entry->d_name;
-
- // ignore "." and ".."
- if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
- continue;
+ if (doProcessDirectoryEntry(path, pathRemaining, client, noMedia, entry, fileSpot)
+ == MEDIA_SCAN_RESULT_ERROR) {
+ result = MEDIA_SCAN_RESULT_ERROR;
+ break;
}
+ }
+ closedir(dir);
+ return result;
+}
- int nameLength = strlen(name);
- if (nameLength + 1 > pathRemaining) {
- // path too long!
- continue;
- }
- strcpy(fileSpot, name);
-
- int type = entry->d_type;
- if (type == DT_UNKNOWN) {
- // If the type is unknown, stat() the file instead.
- // This is sometimes necessary when accessing NFS mounted filesystems, but
- // could be needed in other cases well.
- if (stat(path, &statbuf) == 0) {
- if (S_ISREG(statbuf.st_mode)) {
- type = DT_REG;
- } else if (S_ISDIR(statbuf.st_mode)) {
- type = DT_DIR;
- }
- } else {
- LOGD("stat() failed for %s: %s", path, strerror(errno) );
+MediaScanResult MediaScanner::doProcessDirectoryEntry(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia,
+ struct dirent* entry, char* fileSpot) {
+ struct stat statbuf;
+ const char* name = entry->d_name;
+
+ // ignore "." and ".."
+ if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
+ return MEDIA_SCAN_RESULT_SKIPPED;
+ }
+
+ int nameLength = strlen(name);
+ if (nameLength + 1 > pathRemaining) {
+ // path too long!
+ return MEDIA_SCAN_RESULT_SKIPPED;
+ }
+ strcpy(fileSpot, name);
+
+ int type = entry->d_type;
+ if (type == DT_UNKNOWN) {
+ // If the type is unknown, stat() the file instead.
+ // This is sometimes necessary when accessing NFS mounted filesystems, but
+ // could be needed in other cases well.
+ if (stat(path, &statbuf) == 0) {
+ if (S_ISREG(statbuf.st_mode)) {
+ type = DT_REG;
+ } else if (S_ISDIR(statbuf.st_mode)) {
+ type = DT_DIR;
}
+ } else {
+ LOGD("stat() failed for %s: %s", path, strerror(errno) );
}
- if (type == DT_REG || type == DT_DIR) {
- if (type == DT_DIR) {
- bool childNoMedia = noMedia;
- // set noMedia flag on directories with a name that starts with '.'
- // for example, the Mac ".Trashes" directory
- if (name[0] == '.')
- childNoMedia = true;
-
- // report the directory to the client
- if (stat(path, &statbuf) == 0) {
- client.scanFile(path, statbuf.st_mtime, 0, true, childNoMedia);
- }
-
- // and now process its contents
- strcat(fileSpot, "/");
- int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client,
- childNoMedia, exceptionCheck, exceptionEnv);
- if (err) {
- // pass exceptions up - ignore other errors
- if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure;
- LOGE("Error processing '%s' - skipping\n", path);
- continue;
- }
- } else {
- stat(path, &statbuf);
- client.scanFile(path, statbuf.st_mtime, statbuf.st_size, false, noMedia);
- if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure;
+ }
+ if (type == DT_DIR) {
+ bool childNoMedia = noMedia;
+ // set noMedia flag on directories with a name that starts with '.'
+ // for example, the Mac ".Trashes" directory
+ if (name[0] == '.')
+ childNoMedia = true;
+
+ // report the directory to the client
+ if (stat(path, &statbuf) == 0) {
+ status_t status = client.scanFile(path, statbuf.st_mtime, 0,
+ true /*isDirectory*/, childNoMedia);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
}
}
+
+ // and now process its contents
+ strcat(fileSpot, "/");
+ MediaScanResult result = doProcessDirectory(path, pathRemaining - nameLength - 1,
+ client, childNoMedia);
+ if (result == MEDIA_SCAN_RESULT_ERROR) {
+ return MEDIA_SCAN_RESULT_ERROR;
+ }
+ } else if (type == DT_REG) {
+ stat(path, &statbuf);
+ status_t status = client.scanFile(path, statbuf.st_mtime, statbuf.st_size,
+ false /*isDirectory*/, noMedia);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
+ }
}
- closedir(dir);
- return OK;
-failure:
- closedir(dir);
- return -1;
+ return MEDIA_SCAN_RESULT_OK;
}
} // namespace android
diff --git a/media/libmedia/MediaScannerClient.cpp b/media/libmedia/MediaScannerClient.cpp
index bd3596e..7a7aeb6 100644
--- a/media/libmedia/MediaScannerClient.cpp
+++ b/media/libmedia/MediaScannerClient.cpp
@@ -62,7 +62,7 @@ void MediaScannerClient::beginFile()
mValues = new StringArray;
}
-bool MediaScannerClient::addStringTag(const char* name, const char* value)
+status_t MediaScannerClient::addStringTag(const char* name, const char* value)
{
if (mLocaleEncoding != kEncodingNone) {
// don't bother caching strings that are all ASCII.
@@ -212,8 +212,10 @@ void MediaScannerClient::endFile()
// finally, push all name/value pairs to the client
for (int i = 0; i < mNames->size(); i++) {
- if (!handleStringTag(mNames->getEntry(i), mValues->getEntry(i)))
+ status_t status = handleStringTag(mNames->getEntry(i), mValues->getEntry(i));
+ if (status) {
break;
+ }
}
}
// else addStringTag() has done all the work so we have nothing to do