Loading include/media/mediascanner.h +2 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,8 @@ public: bool addStringTag(const char* name, const char* value); void endFile(); virtual bool scanFile(const char* path, long long lastModified, long long fileSize) = 0; virtual bool scanFile(const char* path, long long lastModified, long long fileSize, bool isDirectory) = 0; virtual bool handleStringTag(const char* name, const char* value) = 0; virtual bool setMimeType(const char* mimeType) = 0; virtual bool addNoMediaFolder(const char* path) = 0; Loading media/java/android/media/MediaScanner.java +63 −54 Original line number Diff line number Diff line Loading @@ -407,8 +407,13 @@ public class MediaScanner private long mFileSize; private String mWriter; public FileCacheEntry beginFile(String path, String mimeType, long lastModified, long fileSize) { public FileCacheEntry beginFile(String path, String mimeType, long lastModified, long fileSize, boolean isDirectory) { mMimeType = mimeType; mFileType = 0; mFileSize = fileSize; if (!isDirectory) { // special case certain file names // I use regionMatches() instead of substring() below // to avoid memory allocation Loading @@ -420,24 +425,23 @@ public class MediaScanner } // ignore album art files created by Windows Media Player: // Folder.jpg, AlbumArtSmall.jpg, AlbumArt_{...}_Large.jpg and AlbumArt_{...}_Small.jpg // Folder.jpg, AlbumArtSmall.jpg, AlbumArt_{...}_Large.jpg // and AlbumArt_{...}_Small.jpg if (path.regionMatches(true, path.length() - 4, ".jpg", 0, 4)) { if (path.regionMatches(true, lastSlash + 1, "AlbumArt_{", 0, 10) || path.regionMatches(true, lastSlash + 1, "AlbumArt.", 0, 9)) { return null; } int length = path.length() - lastSlash - 1; if ((length == 17 && path.regionMatches(true, lastSlash + 1, "AlbumArtSmall", 0, 13)) || (length == 10 && path.regionMatches(true, lastSlash + 1, "Folder", 0, 6))) { if ((length == 17 && path.regionMatches( true, lastSlash + 1, "AlbumArtSmall", 0, 13)) || (length == 10 && path.regionMatches(true, lastSlash + 1, "Folder", 0, 6))) { return null; } } } mMimeType = mimeType; mFileType = 0; mFileSize = fileSize; // try mimeType first, if it is specified if (mimeType != null) { mFileType = MediaFile.getFileTypeForMimeType(mimeType); Loading @@ -457,6 +461,7 @@ public class MediaScanner if (isDrmEnabled() && MediaFile.isDrmFileType(mFileType)) { mFileType = getFileTypeFromDrm(path); } } String key = path; if (mMediaStoragePath != null && key.startsWith(mMediaStoragePath)) { Loading @@ -470,7 +475,9 @@ public class MediaScanner FileCacheEntry entry = mFileCache.get(key); if (entry == null) { Uri tableUri; if (MediaFile.isVideoFileType(mFileType)) { if (isDirectory) { tableUri = mFilesUri; } else if (MediaFile.isVideoFileType(mFileType)) { tableUri = mVideoUri; } else if (MediaFile.isImageFileType(mFileType)) { tableUri = mImagesUri; Loading @@ -479,7 +486,8 @@ public class MediaScanner } else { tableUri = mFilesUri; } entry = new FileCacheEntry(tableUri, 0, path, 0, 0); entry = new FileCacheEntry(tableUri, 0, path, 0, (isDirectory ? MtpConstants.FORMAT_ASSOCIATION : 0)); mFileCache.put(key, entry); } entry.mSeenInFileSystem = true; Loading Loading @@ -514,22 +522,19 @@ public class MediaScanner return entry; } public void scanFile(String path, long lastModified, long fileSize) { public void scanFile(String path, long lastModified, long fileSize, boolean isDirectory) { // This is the callback funtion from native codes. // Log.v(TAG, "scanFile: "+path); doScanFile(path, null, lastModified, fileSize, false); } public void scanFile(String path, String mimeType, long lastModified, long fileSize) { doScanFile(path, mimeType, lastModified, fileSize, false); doScanFile(path, null, lastModified, fileSize, isDirectory, false); } public Uri doScanFile(String path, String mimeType, long lastModified, long fileSize, boolean scanAlways) { long fileSize, boolean isDirectory, boolean scanAlways) { Uri result = null; // long t1 = System.currentTimeMillis(); try { FileCacheEntry entry = beginFile(path, mimeType, lastModified, fileSize); FileCacheEntry entry = beginFile(path, mimeType, lastModified, fileSize, isDirectory); // rescan for metadata if file was modified since last scan if (entry != null && (entry.mLastModifiedChanged || scanAlways)) { String lowpath = path.toLowerCase(); Loading Loading @@ -775,7 +780,11 @@ public class MediaScanner values.put(MediaStore.MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, mMtpObjectHandle); } if (tableUri == mFilesUri) { values.put(Files.FileColumns.FORMAT, MediaFile.getFormatCode(entry.mPath, mMimeType)); int format = entry.mFormat; if (format == 0) { format = MediaFile.getFormatCode(entry.mPath, mMimeType); } values.put(Files.FileColumns.FORMAT, format); } // new file, insert it result = mMediaProvider.insert(tableUri, values); Loading Loading @@ -1060,8 +1069,7 @@ public class MediaScanner boolean fileMissing = false; if (!entry.mSeenInFileSystem && !MtpConstants.isAbstractObject(entry.mFormat)) { if (entry.mFormat != MtpConstants.FORMAT_ASSOCIATION && inScanDirectory(path, directories)) { if (inScanDirectory(path, directories)) { // we didn't see this file in the scan directory. fileMissing = true; } else { Loading Loading @@ -1180,7 +1188,7 @@ public class MediaScanner long lastModifiedSeconds = file.lastModified() / 1000; // always scan the file, so we can return the content://media Uri for existing files return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(), true); return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(),false, true); } catch (RemoteException e) { Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e); return null; Loading Loading @@ -1227,7 +1235,8 @@ public class MediaScanner long lastModifiedSeconds = file.lastModified() / 1000; // always scan the file, so we can return the content://media Uri for existing files mClient.doScanFile(path, mediaFileType.mimeType, lastModifiedSeconds, file.length(), true); mClient.doScanFile(path, mediaFileType.mimeType, lastModifiedSeconds, file.length(), (format == MtpConstants.FORMAT_ASSOCIATION), true); } } catch (RemoteException e) { Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e); Loading media/java/android/media/MediaScannerClient.java +1 −3 Original line number Diff line number Diff line Loading @@ -21,9 +21,7 @@ package android.media; */ public interface MediaScannerClient { public void scanFile(String path, long lastModified, long fileSize); public void scanFile(String path, String mimeType, long lastModified, long fileSize); public void scanFile(String path, long lastModified, long fileSize, boolean isDirectory); public void addNoMediaFolder(String path); Loading media/jni/android_media_MediaScanner.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ public: } else { mScanFileMethodID = env->GetMethodID(mediaScannerClientInterface, "scanFile", "(Ljava/lang/String;JJ)V"); "(Ljava/lang/String;JJZ)V"); mHandleStringTagMethodID = env->GetMethodID(mediaScannerClientInterface, "handleStringTag", "(Ljava/lang/String;Ljava/lang/String;)V"); mSetMimeTypeMethodID = env->GetMethodID(mediaScannerClientInterface, "setMimeType", Loading @@ -78,12 +78,14 @@ public: } // returns true if it succeeded, false if an exception occured in the Java code virtual bool scanFile(const char* path, long long lastModified, long long fileSize) virtual bool scanFile(const char* path, long long lastModified, long long fileSize, bool isDirectory) { jstring pathStr; if ((pathStr = mEnv->NewStringUTF(path)) == NULL) return false; mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified, fileSize); mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified, fileSize, isDirectory); mEnv->DeleteLocalRef(pathStr); return (!mEnv->ExceptionCheck()); Loading media/libmedia/MediaScanner.cpp +10 −6 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ status_t MediaScanner::doProcessDirectory( // place to copy file or directory name char* fileSpot = path + strlen(path); struct dirent* entry; struct stat statbuf; // ignore directories that contain a ".nomedia" file if (pathRemaining >= 8 /* strlen(".nomedia") */ ) { Loading Loading @@ -125,7 +126,6 @@ status_t MediaScanner::doProcessDirectory( // 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. struct stat statbuf; if (stat(path, &statbuf) == 0) { if (S_ISREG(statbuf.st_mode)) { type = DT_REG; Loading @@ -142,8 +142,15 @@ status_t MediaScanner::doProcessDirectory( // for example, the Mac ".Trashes" directory if (name[0] == '.') continue; // report the directory to the client if (stat(path, &statbuf) == 0) { client.scanFile(path, statbuf.st_mtime, 0, true); } // and now process its contents strcat(fileSpot, "/"); int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client, exceptionCheck, exceptionEnv); int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client, exceptionCheck, exceptionEnv); if (err) { // pass exceptions up - ignore other errors if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure; Loading @@ -151,11 +158,8 @@ status_t MediaScanner::doProcessDirectory( continue; } } else { struct stat statbuf; stat(path, &statbuf); if (statbuf.st_size > 0) { client.scanFile(path, statbuf.st_mtime, statbuf.st_size); } client.scanFile(path, statbuf.st_mtime, statbuf.st_size, false); if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure; } } Loading Loading
include/media/mediascanner.h +2 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,8 @@ public: bool addStringTag(const char* name, const char* value); void endFile(); virtual bool scanFile(const char* path, long long lastModified, long long fileSize) = 0; virtual bool scanFile(const char* path, long long lastModified, long long fileSize, bool isDirectory) = 0; virtual bool handleStringTag(const char* name, const char* value) = 0; virtual bool setMimeType(const char* mimeType) = 0; virtual bool addNoMediaFolder(const char* path) = 0; Loading
media/java/android/media/MediaScanner.java +63 −54 Original line number Diff line number Diff line Loading @@ -407,8 +407,13 @@ public class MediaScanner private long mFileSize; private String mWriter; public FileCacheEntry beginFile(String path, String mimeType, long lastModified, long fileSize) { public FileCacheEntry beginFile(String path, String mimeType, long lastModified, long fileSize, boolean isDirectory) { mMimeType = mimeType; mFileType = 0; mFileSize = fileSize; if (!isDirectory) { // special case certain file names // I use regionMatches() instead of substring() below // to avoid memory allocation Loading @@ -420,24 +425,23 @@ public class MediaScanner } // ignore album art files created by Windows Media Player: // Folder.jpg, AlbumArtSmall.jpg, AlbumArt_{...}_Large.jpg and AlbumArt_{...}_Small.jpg // Folder.jpg, AlbumArtSmall.jpg, AlbumArt_{...}_Large.jpg // and AlbumArt_{...}_Small.jpg if (path.regionMatches(true, path.length() - 4, ".jpg", 0, 4)) { if (path.regionMatches(true, lastSlash + 1, "AlbumArt_{", 0, 10) || path.regionMatches(true, lastSlash + 1, "AlbumArt.", 0, 9)) { return null; } int length = path.length() - lastSlash - 1; if ((length == 17 && path.regionMatches(true, lastSlash + 1, "AlbumArtSmall", 0, 13)) || (length == 10 && path.regionMatches(true, lastSlash + 1, "Folder", 0, 6))) { if ((length == 17 && path.regionMatches( true, lastSlash + 1, "AlbumArtSmall", 0, 13)) || (length == 10 && path.regionMatches(true, lastSlash + 1, "Folder", 0, 6))) { return null; } } } mMimeType = mimeType; mFileType = 0; mFileSize = fileSize; // try mimeType first, if it is specified if (mimeType != null) { mFileType = MediaFile.getFileTypeForMimeType(mimeType); Loading @@ -457,6 +461,7 @@ public class MediaScanner if (isDrmEnabled() && MediaFile.isDrmFileType(mFileType)) { mFileType = getFileTypeFromDrm(path); } } String key = path; if (mMediaStoragePath != null && key.startsWith(mMediaStoragePath)) { Loading @@ -470,7 +475,9 @@ public class MediaScanner FileCacheEntry entry = mFileCache.get(key); if (entry == null) { Uri tableUri; if (MediaFile.isVideoFileType(mFileType)) { if (isDirectory) { tableUri = mFilesUri; } else if (MediaFile.isVideoFileType(mFileType)) { tableUri = mVideoUri; } else if (MediaFile.isImageFileType(mFileType)) { tableUri = mImagesUri; Loading @@ -479,7 +486,8 @@ public class MediaScanner } else { tableUri = mFilesUri; } entry = new FileCacheEntry(tableUri, 0, path, 0, 0); entry = new FileCacheEntry(tableUri, 0, path, 0, (isDirectory ? MtpConstants.FORMAT_ASSOCIATION : 0)); mFileCache.put(key, entry); } entry.mSeenInFileSystem = true; Loading Loading @@ -514,22 +522,19 @@ public class MediaScanner return entry; } public void scanFile(String path, long lastModified, long fileSize) { public void scanFile(String path, long lastModified, long fileSize, boolean isDirectory) { // This is the callback funtion from native codes. // Log.v(TAG, "scanFile: "+path); doScanFile(path, null, lastModified, fileSize, false); } public void scanFile(String path, String mimeType, long lastModified, long fileSize) { doScanFile(path, mimeType, lastModified, fileSize, false); doScanFile(path, null, lastModified, fileSize, isDirectory, false); } public Uri doScanFile(String path, String mimeType, long lastModified, long fileSize, boolean scanAlways) { long fileSize, boolean isDirectory, boolean scanAlways) { Uri result = null; // long t1 = System.currentTimeMillis(); try { FileCacheEntry entry = beginFile(path, mimeType, lastModified, fileSize); FileCacheEntry entry = beginFile(path, mimeType, lastModified, fileSize, isDirectory); // rescan for metadata if file was modified since last scan if (entry != null && (entry.mLastModifiedChanged || scanAlways)) { String lowpath = path.toLowerCase(); Loading Loading @@ -775,7 +780,11 @@ public class MediaScanner values.put(MediaStore.MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, mMtpObjectHandle); } if (tableUri == mFilesUri) { values.put(Files.FileColumns.FORMAT, MediaFile.getFormatCode(entry.mPath, mMimeType)); int format = entry.mFormat; if (format == 0) { format = MediaFile.getFormatCode(entry.mPath, mMimeType); } values.put(Files.FileColumns.FORMAT, format); } // new file, insert it result = mMediaProvider.insert(tableUri, values); Loading Loading @@ -1060,8 +1069,7 @@ public class MediaScanner boolean fileMissing = false; if (!entry.mSeenInFileSystem && !MtpConstants.isAbstractObject(entry.mFormat)) { if (entry.mFormat != MtpConstants.FORMAT_ASSOCIATION && inScanDirectory(path, directories)) { if (inScanDirectory(path, directories)) { // we didn't see this file in the scan directory. fileMissing = true; } else { Loading Loading @@ -1180,7 +1188,7 @@ public class MediaScanner long lastModifiedSeconds = file.lastModified() / 1000; // always scan the file, so we can return the content://media Uri for existing files return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(), true); return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(),false, true); } catch (RemoteException e) { Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e); return null; Loading Loading @@ -1227,7 +1235,8 @@ public class MediaScanner long lastModifiedSeconds = file.lastModified() / 1000; // always scan the file, so we can return the content://media Uri for existing files mClient.doScanFile(path, mediaFileType.mimeType, lastModifiedSeconds, file.length(), true); mClient.doScanFile(path, mediaFileType.mimeType, lastModifiedSeconds, file.length(), (format == MtpConstants.FORMAT_ASSOCIATION), true); } } catch (RemoteException e) { Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e); Loading
media/java/android/media/MediaScannerClient.java +1 −3 Original line number Diff line number Diff line Loading @@ -21,9 +21,7 @@ package android.media; */ public interface MediaScannerClient { public void scanFile(String path, long lastModified, long fileSize); public void scanFile(String path, String mimeType, long lastModified, long fileSize); public void scanFile(String path, long lastModified, long fileSize, boolean isDirectory); public void addNoMediaFolder(String path); Loading
media/jni/android_media_MediaScanner.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ public: } else { mScanFileMethodID = env->GetMethodID(mediaScannerClientInterface, "scanFile", "(Ljava/lang/String;JJ)V"); "(Ljava/lang/String;JJZ)V"); mHandleStringTagMethodID = env->GetMethodID(mediaScannerClientInterface, "handleStringTag", "(Ljava/lang/String;Ljava/lang/String;)V"); mSetMimeTypeMethodID = env->GetMethodID(mediaScannerClientInterface, "setMimeType", Loading @@ -78,12 +78,14 @@ public: } // returns true if it succeeded, false if an exception occured in the Java code virtual bool scanFile(const char* path, long long lastModified, long long fileSize) virtual bool scanFile(const char* path, long long lastModified, long long fileSize, bool isDirectory) { jstring pathStr; if ((pathStr = mEnv->NewStringUTF(path)) == NULL) return false; mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified, fileSize); mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified, fileSize, isDirectory); mEnv->DeleteLocalRef(pathStr); return (!mEnv->ExceptionCheck()); Loading
media/libmedia/MediaScanner.cpp +10 −6 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ status_t MediaScanner::doProcessDirectory( // place to copy file or directory name char* fileSpot = path + strlen(path); struct dirent* entry; struct stat statbuf; // ignore directories that contain a ".nomedia" file if (pathRemaining >= 8 /* strlen(".nomedia") */ ) { Loading Loading @@ -125,7 +126,6 @@ status_t MediaScanner::doProcessDirectory( // 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. struct stat statbuf; if (stat(path, &statbuf) == 0) { if (S_ISREG(statbuf.st_mode)) { type = DT_REG; Loading @@ -142,8 +142,15 @@ status_t MediaScanner::doProcessDirectory( // for example, the Mac ".Trashes" directory if (name[0] == '.') continue; // report the directory to the client if (stat(path, &statbuf) == 0) { client.scanFile(path, statbuf.st_mtime, 0, true); } // and now process its contents strcat(fileSpot, "/"); int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client, exceptionCheck, exceptionEnv); int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client, exceptionCheck, exceptionEnv); if (err) { // pass exceptions up - ignore other errors if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure; Loading @@ -151,11 +158,8 @@ status_t MediaScanner::doProcessDirectory( continue; } } else { struct stat statbuf; stat(path, &statbuf); if (statbuf.st_size > 0) { client.scanFile(path, statbuf.st_mtime, statbuf.st_size); } client.scanFile(path, statbuf.st_mtime, statbuf.st_size, false); if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure; } } Loading