From fb6f03425a791dcc4188462c860becf6ca6be4ea Mon Sep 17 00:00:00 2001 From: Guang Zhu Date: Wed, 7 Sep 2011 23:55:27 -0700 Subject: Make MediaScanner skip certain directories The list of directories to skip are configurable via setprop. The main motivation is that some test data folder takes long time to scan, and media scanner may compete for CPU time against perf tests therefore skewing the results. Bug: 5263115 Change-Id: I568213e2a4babf6033021c1d336ef0347c0e3315 --- media/libmedia/MediaScanner.cpp | 60 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'media/libmedia') diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp index 41f8593..19dedfc 100644 --- a/media/libmedia/MediaScanner.cpp +++ b/media/libmedia/MediaScanner.cpp @@ -16,6 +16,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "MediaScanner" +#include #include #include @@ -26,11 +27,14 @@ namespace android { MediaScanner::MediaScanner() - : mLocale(NULL) { + : mLocale(NULL), mSkipList(NULL), mSkipIndex(NULL) { + loadSkipList(); } MediaScanner::~MediaScanner() { setLocale(NULL); + free(mSkipList); + free(mSkipIndex); } void MediaScanner::setLocale(const char *locale) { @@ -47,6 +51,33 @@ const char *MediaScanner::locale() const { return mLocale; } +void MediaScanner::loadSkipList() { + mSkipList = (char *)malloc(PROPERTY_VALUE_MAX * sizeof(char)); + if (mSkipList) { + property_get("testing.mediascanner.skiplist", mSkipList, ""); + } + if (!mSkipList || (strlen(mSkipList) == 0)) { + free(mSkipList); + mSkipList = NULL; + return; + } + mSkipIndex = (int *)malloc(PROPERTY_VALUE_MAX * sizeof(int)); + if (mSkipIndex) { + // dup it because strtok will modify the string + char *skipList = strdup(mSkipList); + if (skipList) { + char * path = strtok(skipList, ","); + int i = 0; + while (path) { + mSkipIndex[i++] = strlen(path); + path = strtok(NULL, ","); + } + mSkipIndex[i] = -1; + free(skipList); + } + } +} + MediaScanResult MediaScanner::processDirectory( const char *path, MediaScannerClient &client) { int pathLength = strlen(path); @@ -75,12 +106,39 @@ MediaScanResult MediaScanner::processDirectory( return result; } +bool MediaScanner::shouldSkipDirectory(char *path) { + if (path && mSkipList && mSkipIndex) { + int len = strlen(path); + int idx = 0; + // track the start position of next path in the comma + // separated list obtained from getprop + int startPos = 0; + while (mSkipIndex[idx] != -1) { + // no point to match path name if strlen mismatch + if ((len == mSkipIndex[idx]) + // pick out the path segment from comma separated list + // to compare against current path parameter + && (strncmp(path, &mSkipList[startPos], len) == 0)) { + return true; + } + startPos += mSkipIndex[idx] + 1; // extra char for the delimiter + idx++; + } + } + return false; +} + 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; + if (shouldSkipDirectory(path)) { + LOGD("Skipping: %s", path); + return MEDIA_SCAN_RESULT_OK; + } + // Treat all files as non-media in directories that contain a ".nomedia" file if (pathRemaining >= 8 /* strlen(".nomedia") */ ) { strcpy(fileSpot, ".nomedia"); -- cgit v1.1