Loading include/media/mediascanner.h +26 −14 Original line number Original line Diff line number Diff line Loading @@ -23,23 +23,33 @@ #include <utils/Errors.h> #include <utils/Errors.h> #include <pthread.h> #include <pthread.h> struct dirent; namespace android { namespace android { class MediaScannerClient; class MediaScannerClient; class StringArray; class StringArray; enum MediaScanResult { // This file or directory was scanned successfully. MEDIA_SCAN_RESULT_OK, // This file or directory was skipped because it was not found, could // not be opened, was of an unsupported type, or was malfored in some way. MEDIA_SCAN_RESULT_SKIPPED, // The scan should be aborted due to a fatal error such as out of memory // or an exception. MEDIA_SCAN_RESULT_ERROR, }; struct MediaScanner { struct MediaScanner { MediaScanner(); MediaScanner(); virtual ~MediaScanner(); virtual ~MediaScanner(); virtual status_t processFile( virtual MediaScanResult processFile( const char *path, const char *mimeType, const char *path, const char *mimeType, MediaScannerClient &client) = 0; MediaScannerClient &client) = 0; typedef bool (*ExceptionCheck)(void* env); virtual MediaScanResult processDirectory( virtual status_t processDirectory( const char *path, MediaScannerClient &client); const char *path, MediaScannerClient &client, ExceptionCheck exceptionCheck, void *exceptionEnv); void setLocale(const char *locale); void setLocale(const char *locale); Loading @@ -53,9 +63,11 @@ private: // current locale (like "ja_JP"), created/destroyed with strdup()/free() // current locale (like "ja_JP"), created/destroyed with strdup()/free() char *mLocale; char *mLocale; status_t doProcessDirectory( MediaScanResult doProcessDirectory( char *path, int pathRemaining, MediaScannerClient &client, char *path, int pathRemaining, MediaScannerClient &client, bool noMedia); bool noMedia, ExceptionCheck exceptionCheck, void *exceptionEnv); MediaScanResult doProcessDirectoryEntry( char *path, int pathRemaining, MediaScannerClient &client, bool noMedia, struct dirent* entry, char* fileSpot); MediaScanner(const MediaScanner &); MediaScanner(const MediaScanner &); MediaScanner &operator=(const MediaScanner &); MediaScanner &operator=(const MediaScanner &); Loading @@ -68,13 +80,13 @@ public: virtual ~MediaScannerClient(); virtual ~MediaScannerClient(); void setLocale(const char* locale); void setLocale(const char* locale); void beginFile(); void beginFile(); bool addStringTag(const char* name, const char* value); status_t addStringTag(const char* name, const char* value); void endFile(); void endFile(); virtual bool scanFile(const char* path, long long lastModified, virtual status_t scanFile(const char* path, long long lastModified, long long fileSize, bool isDirectory, bool noMedia) = 0; long long fileSize, bool isDirectory, bool noMedia) = 0; virtual bool handleStringTag(const char* name, const char* value) = 0; virtual status_t handleStringTag(const char* name, const char* value) = 0; virtual bool setMimeType(const char* mimeType) = 0; virtual status_t setMimeType(const char* mimeType) = 0; protected: protected: void convertValues(uint32_t encoding); void convertValues(uint32_t encoding); Loading include/media/stagefright/StagefrightMediaScanner.h +5 −1 Original line number Original line Diff line number Diff line Loading @@ -26,7 +26,7 @@ struct StagefrightMediaScanner : public MediaScanner { StagefrightMediaScanner(); StagefrightMediaScanner(); virtual ~StagefrightMediaScanner(); virtual ~StagefrightMediaScanner(); virtual status_t processFile( virtual MediaScanResult processFile( const char *path, const char *mimeType, const char *path, const char *mimeType, MediaScannerClient &client); MediaScannerClient &client); Loading @@ -35,6 +35,10 @@ struct StagefrightMediaScanner : public MediaScanner { private: private: StagefrightMediaScanner(const StagefrightMediaScanner &); StagefrightMediaScanner(const StagefrightMediaScanner &); StagefrightMediaScanner &operator=(const StagefrightMediaScanner &); StagefrightMediaScanner &operator=(const StagefrightMediaScanner &); MediaScanResult processFileInternal( const char *path, const char *mimeType, MediaScannerClient &client); }; }; } // namespace android } // namespace android Loading media/libmedia/MediaScanner.cpp +78 −70 Original line number Original line Diff line number Diff line Loading @@ -47,16 +47,15 @@ const char *MediaScanner::locale() const { return mLocale; return mLocale; } } status_t MediaScanner::processDirectory( MediaScanResult MediaScanner::processDirectory( const char *path, MediaScannerClient &client, const char *path, MediaScannerClient &client) { ExceptionCheck exceptionCheck, void *exceptionEnv) { int pathLength = strlen(path); int pathLength = strlen(path); if (pathLength >= PATH_MAX) { if (pathLength >= PATH_MAX) { return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_SKIPPED; } } char* pathBuffer = (char *)malloc(PATH_MAX + 1); char* pathBuffer = (char *)malloc(PATH_MAX + 1); if (!pathBuffer) { if (!pathBuffer) { return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_ERROR; } } int pathRemaining = PATH_MAX - pathLength; int pathRemaining = PATH_MAX - pathLength; Loading @@ -69,21 +68,18 @@ status_t MediaScanner::processDirectory( client.setLocale(locale()); client.setLocale(locale()); status_t result = MediaScanResult result = doProcessDirectory(pathBuffer, pathRemaining, client, false); doProcessDirectory(pathBuffer, pathRemaining, client, false, exceptionCheck, exceptionEnv); free(pathBuffer); free(pathBuffer); return result; return result; } } status_t MediaScanner::doProcessDirectory( MediaScanResult MediaScanner::doProcessDirectory( char *path, int pathRemaining, MediaScannerClient &client, char *path, int pathRemaining, MediaScannerClient &client, bool noMedia) { bool noMedia, ExceptionCheck exceptionCheck, void *exceptionEnv) { // place to copy file or directory name // place to copy file or directory name char* fileSpot = path + strlen(path); char* fileSpot = path + strlen(path); struct dirent* entry; struct dirent* entry; struct stat statbuf; // Treat all files as non-media in directories that contain a ".nomedia" file // Treat all files as non-media in directories that contain a ".nomedia" file if (pathRemaining >= 8 /* strlen(".nomedia") */ ) { if (pathRemaining >= 8 /* strlen(".nomedia") */ ) { Loading @@ -99,22 +95,37 @@ status_t MediaScanner::doProcessDirectory( DIR* dir = opendir(path); DIR* dir = opendir(path); if (!dir) { if (!dir) { LOGD("opendir %s failed, errno: %d", path, errno); LOGW("Error opening directory '%s', skipping: %s.", path, strerror(errno)); return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_SKIPPED; } } MediaScanResult result = MEDIA_SCAN_RESULT_OK; while ((entry = readdir(dir))) { while ((entry = readdir(dir))) { if (doProcessDirectoryEntry(path, pathRemaining, client, noMedia, entry, fileSpot) == MEDIA_SCAN_RESULT_ERROR) { result = MEDIA_SCAN_RESULT_ERROR; break; } } closedir(dir); return result; } 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; const char* name = entry->d_name; // ignore "." and ".." // ignore "." and ".." if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) { if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) { continue; return MEDIA_SCAN_RESULT_SKIPPED; } } int nameLength = strlen(name); int nameLength = strlen(name); if (nameLength + 1 > pathRemaining) { if (nameLength + 1 > pathRemaining) { // path too long! // path too long! continue; return MEDIA_SCAN_RESULT_SKIPPED; } } strcpy(fileSpot, name); strcpy(fileSpot, name); Loading @@ -133,7 +144,6 @@ status_t MediaScanner::doProcessDirectory( LOGD("stat() failed for %s: %s", path, strerror(errno) ); LOGD("stat() failed for %s: %s", path, strerror(errno) ); } } } } if (type == DT_REG || type == DT_DIR) { if (type == DT_DIR) { if (type == DT_DIR) { bool childNoMedia = noMedia; bool childNoMedia = noMedia; // set noMedia flag on directories with a name that starts with '.' // set noMedia flag on directories with a name that starts with '.' Loading @@ -143,32 +153,30 @@ status_t MediaScanner::doProcessDirectory( // report the directory to the client // report the directory to the client if (stat(path, &statbuf) == 0) { if (stat(path, &statbuf) == 0) { client.scanFile(path, statbuf.st_mtime, 0, true, childNoMedia); 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 // and now process its contents strcat(fileSpot, "/"); strcat(fileSpot, "/"); int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client, MediaScanResult result = doProcessDirectory(path, pathRemaining - nameLength - 1, childNoMedia, exceptionCheck, exceptionEnv); client, childNoMedia); if (err) { if (result == MEDIA_SCAN_RESULT_ERROR) { // pass exceptions up - ignore other errors return MEDIA_SCAN_RESULT_ERROR; if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure; LOGE("Error processing '%s' - skipping\n", path); continue; } } } else { } else if (type == DT_REG) { stat(path, &statbuf); stat(path, &statbuf); client.scanFile(path, statbuf.st_mtime, statbuf.st_size, false, noMedia); status_t status = client.scanFile(path, statbuf.st_mtime, statbuf.st_size, if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure; false /*isDirectory*/, noMedia); } if (status) { return MEDIA_SCAN_RESULT_ERROR; } } } } closedir(dir); return MEDIA_SCAN_RESULT_OK; return OK; failure: closedir(dir); return -1; } } } // namespace android } // namespace android media/libmedia/MediaScannerClient.cpp +4 −2 Original line number Original line Diff line number Diff line Loading @@ -62,7 +62,7 @@ void MediaScannerClient::beginFile() mValues = new StringArray; 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) { if (mLocaleEncoding != kEncodingNone) { // don't bother caching strings that are all ASCII. // don't bother caching strings that are all ASCII. Loading Loading @@ -212,10 +212,12 @@ void MediaScannerClient::endFile() // finally, push all name/value pairs to the client // finally, push all name/value pairs to the client for (int i = 0; i < mNames->size(); i++) { 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; break; } } } } } // else addStringTag() has done all the work so we have nothing to do // else addStringTag() has done all the work so we have nothing to do delete mNames; delete mNames; Loading media/libstagefright/StagefrightMediaScanner.cpp +63 −52 Original line number Original line Diff line number Diff line Loading @@ -52,13 +52,13 @@ static bool FileHasAcceptableExtension(const char *extension) { return false; return false; } } static status_t HandleMIDI( static MediaScanResult HandleMIDI( const char *filename, MediaScannerClient *client) { const char *filename, MediaScannerClient *client) { // get the library configuration and do sanity check // get the library configuration and do sanity check const S_EAS_LIB_CONFIG* pLibConfig = EAS_Config(); const S_EAS_LIB_CONFIG* pLibConfig = EAS_Config(); if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) { if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) { LOGE("EAS library/header mismatch\n"); LOGE("EAS library/header mismatch\n"); return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_ERROR; } } EAS_I32 temp; EAS_I32 temp; Loading Loading @@ -88,34 +88,41 @@ static status_t HandleMIDI( } } if (result != EAS_SUCCESS) { if (result != EAS_SUCCESS) { return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_SKIPPED; } } char buffer[20]; char buffer[20]; sprintf(buffer, "%ld", temp); sprintf(buffer, "%ld", temp); if (!client->addStringTag("duration", buffer)) return UNKNOWN_ERROR; status_t status = client->addStringTag("duration", buffer); if (status) { return OK; return MEDIA_SCAN_RESULT_ERROR; } return MEDIA_SCAN_RESULT_OK; } } status_t StagefrightMediaScanner::processFile( MediaScanResult StagefrightMediaScanner::processFile( const char *path, const char *mimeType, const char *path, const char *mimeType, MediaScannerClient &client) { MediaScannerClient &client) { LOGV("processFile '%s'.", path); LOGV("processFile '%s'.", path); client.setLocale(locale()); client.setLocale(locale()); client.beginFile(); client.beginFile(); MediaScanResult result = processFileInternal(path, mimeType, client); client.endFile(); return result; } MediaScanResult StagefrightMediaScanner::processFileInternal( const char *path, const char *mimeType, MediaScannerClient &client) { const char *extension = strrchr(path, '.'); const char *extension = strrchr(path, '.'); if (!extension) { if (!extension) { return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_SKIPPED; } } if (!FileHasAcceptableExtension(extension)) { if (!FileHasAcceptableExtension(extension)) { client.endFile(); return MEDIA_SCAN_RESULT_SKIPPED; return UNKNOWN_ERROR; } } if (!strcasecmp(extension, ".mid") if (!strcasecmp(extension, ".mid") Loading @@ -127,18 +134,23 @@ status_t StagefrightMediaScanner::processFile( || !strcasecmp(extension, ".rtx") || !strcasecmp(extension, ".rtx") || !strcasecmp(extension, ".ota") || !strcasecmp(extension, ".ota") || !strcasecmp(extension, ".mxmf")) { || !strcasecmp(extension, ".mxmf")) { status_t status = HandleMIDI(path, &client); return HandleMIDI(path, &client); if (status != OK) { return status; } } } else { sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever); sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever); if (mRetriever->setDataSource(path) == OK) { status_t status = mRetriever->setDataSource(path); if (status) { return MEDIA_SCAN_RESULT_ERROR; } const char *value; const char *value; if ((value = mRetriever->extractMetadata( if ((value = mRetriever->extractMetadata( METADATA_KEY_MIMETYPE)) != NULL) { METADATA_KEY_MIMETYPE)) != NULL) { client.setMimeType(value); status = client.setMimeType(value); if (status) { return MEDIA_SCAN_RESULT_ERROR; } } } struct KeyMap { struct KeyMap { Loading @@ -165,15 +177,14 @@ status_t StagefrightMediaScanner::processFile( for (size_t i = 0; i < kNumEntries; ++i) { for (size_t i = 0; i < kNumEntries; ++i) { const char *value; const char *value; if ((value = mRetriever->extractMetadata(kKeyMap[i].key)) != NULL) { if ((value = mRetriever->extractMetadata(kKeyMap[i].key)) != NULL) { client.addStringTag(kKeyMap[i].tag, value); status = client.addStringTag(kKeyMap[i].tag, value); if (status) { return MEDIA_SCAN_RESULT_ERROR; } } } } } } } client.endFile(); return OK; return MEDIA_SCAN_RESULT_OK; } } char *StagefrightMediaScanner::extractAlbumArt(int fd) { char *StagefrightMediaScanner::extractAlbumArt(int fd) { Loading Loading
include/media/mediascanner.h +26 −14 Original line number Original line Diff line number Diff line Loading @@ -23,23 +23,33 @@ #include <utils/Errors.h> #include <utils/Errors.h> #include <pthread.h> #include <pthread.h> struct dirent; namespace android { namespace android { class MediaScannerClient; class MediaScannerClient; class StringArray; class StringArray; enum MediaScanResult { // This file or directory was scanned successfully. MEDIA_SCAN_RESULT_OK, // This file or directory was skipped because it was not found, could // not be opened, was of an unsupported type, or was malfored in some way. MEDIA_SCAN_RESULT_SKIPPED, // The scan should be aborted due to a fatal error such as out of memory // or an exception. MEDIA_SCAN_RESULT_ERROR, }; struct MediaScanner { struct MediaScanner { MediaScanner(); MediaScanner(); virtual ~MediaScanner(); virtual ~MediaScanner(); virtual status_t processFile( virtual MediaScanResult processFile( const char *path, const char *mimeType, const char *path, const char *mimeType, MediaScannerClient &client) = 0; MediaScannerClient &client) = 0; typedef bool (*ExceptionCheck)(void* env); virtual MediaScanResult processDirectory( virtual status_t processDirectory( const char *path, MediaScannerClient &client); const char *path, MediaScannerClient &client, ExceptionCheck exceptionCheck, void *exceptionEnv); void setLocale(const char *locale); void setLocale(const char *locale); Loading @@ -53,9 +63,11 @@ private: // current locale (like "ja_JP"), created/destroyed with strdup()/free() // current locale (like "ja_JP"), created/destroyed with strdup()/free() char *mLocale; char *mLocale; status_t doProcessDirectory( MediaScanResult doProcessDirectory( char *path, int pathRemaining, MediaScannerClient &client, char *path, int pathRemaining, MediaScannerClient &client, bool noMedia); bool noMedia, ExceptionCheck exceptionCheck, void *exceptionEnv); MediaScanResult doProcessDirectoryEntry( char *path, int pathRemaining, MediaScannerClient &client, bool noMedia, struct dirent* entry, char* fileSpot); MediaScanner(const MediaScanner &); MediaScanner(const MediaScanner &); MediaScanner &operator=(const MediaScanner &); MediaScanner &operator=(const MediaScanner &); Loading @@ -68,13 +80,13 @@ public: virtual ~MediaScannerClient(); virtual ~MediaScannerClient(); void setLocale(const char* locale); void setLocale(const char* locale); void beginFile(); void beginFile(); bool addStringTag(const char* name, const char* value); status_t addStringTag(const char* name, const char* value); void endFile(); void endFile(); virtual bool scanFile(const char* path, long long lastModified, virtual status_t scanFile(const char* path, long long lastModified, long long fileSize, bool isDirectory, bool noMedia) = 0; long long fileSize, bool isDirectory, bool noMedia) = 0; virtual bool handleStringTag(const char* name, const char* value) = 0; virtual status_t handleStringTag(const char* name, const char* value) = 0; virtual bool setMimeType(const char* mimeType) = 0; virtual status_t setMimeType(const char* mimeType) = 0; protected: protected: void convertValues(uint32_t encoding); void convertValues(uint32_t encoding); Loading
include/media/stagefright/StagefrightMediaScanner.h +5 −1 Original line number Original line Diff line number Diff line Loading @@ -26,7 +26,7 @@ struct StagefrightMediaScanner : public MediaScanner { StagefrightMediaScanner(); StagefrightMediaScanner(); virtual ~StagefrightMediaScanner(); virtual ~StagefrightMediaScanner(); virtual status_t processFile( virtual MediaScanResult processFile( const char *path, const char *mimeType, const char *path, const char *mimeType, MediaScannerClient &client); MediaScannerClient &client); Loading @@ -35,6 +35,10 @@ struct StagefrightMediaScanner : public MediaScanner { private: private: StagefrightMediaScanner(const StagefrightMediaScanner &); StagefrightMediaScanner(const StagefrightMediaScanner &); StagefrightMediaScanner &operator=(const StagefrightMediaScanner &); StagefrightMediaScanner &operator=(const StagefrightMediaScanner &); MediaScanResult processFileInternal( const char *path, const char *mimeType, MediaScannerClient &client); }; }; } // namespace android } // namespace android Loading
media/libmedia/MediaScanner.cpp +78 −70 Original line number Original line Diff line number Diff line Loading @@ -47,16 +47,15 @@ const char *MediaScanner::locale() const { return mLocale; return mLocale; } } status_t MediaScanner::processDirectory( MediaScanResult MediaScanner::processDirectory( const char *path, MediaScannerClient &client, const char *path, MediaScannerClient &client) { ExceptionCheck exceptionCheck, void *exceptionEnv) { int pathLength = strlen(path); int pathLength = strlen(path); if (pathLength >= PATH_MAX) { if (pathLength >= PATH_MAX) { return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_SKIPPED; } } char* pathBuffer = (char *)malloc(PATH_MAX + 1); char* pathBuffer = (char *)malloc(PATH_MAX + 1); if (!pathBuffer) { if (!pathBuffer) { return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_ERROR; } } int pathRemaining = PATH_MAX - pathLength; int pathRemaining = PATH_MAX - pathLength; Loading @@ -69,21 +68,18 @@ status_t MediaScanner::processDirectory( client.setLocale(locale()); client.setLocale(locale()); status_t result = MediaScanResult result = doProcessDirectory(pathBuffer, pathRemaining, client, false); doProcessDirectory(pathBuffer, pathRemaining, client, false, exceptionCheck, exceptionEnv); free(pathBuffer); free(pathBuffer); return result; return result; } } status_t MediaScanner::doProcessDirectory( MediaScanResult MediaScanner::doProcessDirectory( char *path, int pathRemaining, MediaScannerClient &client, char *path, int pathRemaining, MediaScannerClient &client, bool noMedia) { bool noMedia, ExceptionCheck exceptionCheck, void *exceptionEnv) { // place to copy file or directory name // place to copy file or directory name char* fileSpot = path + strlen(path); char* fileSpot = path + strlen(path); struct dirent* entry; struct dirent* entry; struct stat statbuf; // Treat all files as non-media in directories that contain a ".nomedia" file // Treat all files as non-media in directories that contain a ".nomedia" file if (pathRemaining >= 8 /* strlen(".nomedia") */ ) { if (pathRemaining >= 8 /* strlen(".nomedia") */ ) { Loading @@ -99,22 +95,37 @@ status_t MediaScanner::doProcessDirectory( DIR* dir = opendir(path); DIR* dir = opendir(path); if (!dir) { if (!dir) { LOGD("opendir %s failed, errno: %d", path, errno); LOGW("Error opening directory '%s', skipping: %s.", path, strerror(errno)); return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_SKIPPED; } } MediaScanResult result = MEDIA_SCAN_RESULT_OK; while ((entry = readdir(dir))) { while ((entry = readdir(dir))) { if (doProcessDirectoryEntry(path, pathRemaining, client, noMedia, entry, fileSpot) == MEDIA_SCAN_RESULT_ERROR) { result = MEDIA_SCAN_RESULT_ERROR; break; } } closedir(dir); return result; } 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; const char* name = entry->d_name; // ignore "." and ".." // ignore "." and ".." if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) { if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) { continue; return MEDIA_SCAN_RESULT_SKIPPED; } } int nameLength = strlen(name); int nameLength = strlen(name); if (nameLength + 1 > pathRemaining) { if (nameLength + 1 > pathRemaining) { // path too long! // path too long! continue; return MEDIA_SCAN_RESULT_SKIPPED; } } strcpy(fileSpot, name); strcpy(fileSpot, name); Loading @@ -133,7 +144,6 @@ status_t MediaScanner::doProcessDirectory( LOGD("stat() failed for %s: %s", path, strerror(errno) ); LOGD("stat() failed for %s: %s", path, strerror(errno) ); } } } } if (type == DT_REG || type == DT_DIR) { if (type == DT_DIR) { if (type == DT_DIR) { bool childNoMedia = noMedia; bool childNoMedia = noMedia; // set noMedia flag on directories with a name that starts with '.' // set noMedia flag on directories with a name that starts with '.' Loading @@ -143,32 +153,30 @@ status_t MediaScanner::doProcessDirectory( // report the directory to the client // report the directory to the client if (stat(path, &statbuf) == 0) { if (stat(path, &statbuf) == 0) { client.scanFile(path, statbuf.st_mtime, 0, true, childNoMedia); 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 // and now process its contents strcat(fileSpot, "/"); strcat(fileSpot, "/"); int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client, MediaScanResult result = doProcessDirectory(path, pathRemaining - nameLength - 1, childNoMedia, exceptionCheck, exceptionEnv); client, childNoMedia); if (err) { if (result == MEDIA_SCAN_RESULT_ERROR) { // pass exceptions up - ignore other errors return MEDIA_SCAN_RESULT_ERROR; if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure; LOGE("Error processing '%s' - skipping\n", path); continue; } } } else { } else if (type == DT_REG) { stat(path, &statbuf); stat(path, &statbuf); client.scanFile(path, statbuf.st_mtime, statbuf.st_size, false, noMedia); status_t status = client.scanFile(path, statbuf.st_mtime, statbuf.st_size, if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure; false /*isDirectory*/, noMedia); } if (status) { return MEDIA_SCAN_RESULT_ERROR; } } } } closedir(dir); return MEDIA_SCAN_RESULT_OK; return OK; failure: closedir(dir); return -1; } } } // namespace android } // namespace android
media/libmedia/MediaScannerClient.cpp +4 −2 Original line number Original line Diff line number Diff line Loading @@ -62,7 +62,7 @@ void MediaScannerClient::beginFile() mValues = new StringArray; 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) { if (mLocaleEncoding != kEncodingNone) { // don't bother caching strings that are all ASCII. // don't bother caching strings that are all ASCII. Loading Loading @@ -212,10 +212,12 @@ void MediaScannerClient::endFile() // finally, push all name/value pairs to the client // finally, push all name/value pairs to the client for (int i = 0; i < mNames->size(); i++) { 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; break; } } } } } // else addStringTag() has done all the work so we have nothing to do // else addStringTag() has done all the work so we have nothing to do delete mNames; delete mNames; Loading
media/libstagefright/StagefrightMediaScanner.cpp +63 −52 Original line number Original line Diff line number Diff line Loading @@ -52,13 +52,13 @@ static bool FileHasAcceptableExtension(const char *extension) { return false; return false; } } static status_t HandleMIDI( static MediaScanResult HandleMIDI( const char *filename, MediaScannerClient *client) { const char *filename, MediaScannerClient *client) { // get the library configuration and do sanity check // get the library configuration and do sanity check const S_EAS_LIB_CONFIG* pLibConfig = EAS_Config(); const S_EAS_LIB_CONFIG* pLibConfig = EAS_Config(); if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) { if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) { LOGE("EAS library/header mismatch\n"); LOGE("EAS library/header mismatch\n"); return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_ERROR; } } EAS_I32 temp; EAS_I32 temp; Loading Loading @@ -88,34 +88,41 @@ static status_t HandleMIDI( } } if (result != EAS_SUCCESS) { if (result != EAS_SUCCESS) { return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_SKIPPED; } } char buffer[20]; char buffer[20]; sprintf(buffer, "%ld", temp); sprintf(buffer, "%ld", temp); if (!client->addStringTag("duration", buffer)) return UNKNOWN_ERROR; status_t status = client->addStringTag("duration", buffer); if (status) { return OK; return MEDIA_SCAN_RESULT_ERROR; } return MEDIA_SCAN_RESULT_OK; } } status_t StagefrightMediaScanner::processFile( MediaScanResult StagefrightMediaScanner::processFile( const char *path, const char *mimeType, const char *path, const char *mimeType, MediaScannerClient &client) { MediaScannerClient &client) { LOGV("processFile '%s'.", path); LOGV("processFile '%s'.", path); client.setLocale(locale()); client.setLocale(locale()); client.beginFile(); client.beginFile(); MediaScanResult result = processFileInternal(path, mimeType, client); client.endFile(); return result; } MediaScanResult StagefrightMediaScanner::processFileInternal( const char *path, const char *mimeType, MediaScannerClient &client) { const char *extension = strrchr(path, '.'); const char *extension = strrchr(path, '.'); if (!extension) { if (!extension) { return UNKNOWN_ERROR; return MEDIA_SCAN_RESULT_SKIPPED; } } if (!FileHasAcceptableExtension(extension)) { if (!FileHasAcceptableExtension(extension)) { client.endFile(); return MEDIA_SCAN_RESULT_SKIPPED; return UNKNOWN_ERROR; } } if (!strcasecmp(extension, ".mid") if (!strcasecmp(extension, ".mid") Loading @@ -127,18 +134,23 @@ status_t StagefrightMediaScanner::processFile( || !strcasecmp(extension, ".rtx") || !strcasecmp(extension, ".rtx") || !strcasecmp(extension, ".ota") || !strcasecmp(extension, ".ota") || !strcasecmp(extension, ".mxmf")) { || !strcasecmp(extension, ".mxmf")) { status_t status = HandleMIDI(path, &client); return HandleMIDI(path, &client); if (status != OK) { return status; } } } else { sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever); sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever); if (mRetriever->setDataSource(path) == OK) { status_t status = mRetriever->setDataSource(path); if (status) { return MEDIA_SCAN_RESULT_ERROR; } const char *value; const char *value; if ((value = mRetriever->extractMetadata( if ((value = mRetriever->extractMetadata( METADATA_KEY_MIMETYPE)) != NULL) { METADATA_KEY_MIMETYPE)) != NULL) { client.setMimeType(value); status = client.setMimeType(value); if (status) { return MEDIA_SCAN_RESULT_ERROR; } } } struct KeyMap { struct KeyMap { Loading @@ -165,15 +177,14 @@ status_t StagefrightMediaScanner::processFile( for (size_t i = 0; i < kNumEntries; ++i) { for (size_t i = 0; i < kNumEntries; ++i) { const char *value; const char *value; if ((value = mRetriever->extractMetadata(kKeyMap[i].key)) != NULL) { if ((value = mRetriever->extractMetadata(kKeyMap[i].key)) != NULL) { client.addStringTag(kKeyMap[i].tag, value); status = client.addStringTag(kKeyMap[i].tag, value); if (status) { return MEDIA_SCAN_RESULT_ERROR; } } } } } } } client.endFile(); return OK; return MEDIA_SCAN_RESULT_OK; } } char *StagefrightMediaScanner::extractAlbumArt(int fd) { char *StagefrightMediaScanner::extractAlbumArt(int fd) { Loading