summaryrefslogtreecommitdiffstats
path: root/media/java
diff options
context:
space:
mode:
Diffstat (limited to 'media/java')
-rw-r--r--media/java/android/media/AmrInputStream.java2
-rw-r--r--media/java/android/media/AsyncPlayer.java2
-rw-r--r--media/java/android/media/AudioManager.java47
-rw-r--r--media/java/android/media/AudioRecord.java2
-rw-r--r--media/java/android/media/AudioService.java61
-rw-r--r--media/java/android/media/ExifInterface.java2
-rw-r--r--media/java/android/media/MediaFile.java10
-rw-r--r--media/java/android/media/MediaInserter.java2
-rw-r--r--media/java/android/media/MediaRecorder.java21
-rw-r--r--media/java/android/media/MediaScanner.java40
-rw-r--r--media/java/android/media/MediaScannerConnection.java2
-rw-r--r--media/java/android/media/MiniThumbFile.java2
-rw-r--r--media/java/android/media/RemoteControlClient.java3
-rw-r--r--media/java/android/media/RingtoneManager.java2
-rwxr-xr-xmedia/java/android/mtp/MtpDatabase.java46
-rw-r--r--media/java/android/mtp/MtpPropertyGroup.java10
16 files changed, 158 insertions, 96 deletions
diff --git a/media/java/android/media/AmrInputStream.java b/media/java/android/media/AmrInputStream.java
index bc68472..8b7eee2 100644
--- a/media/java/android/media/AmrInputStream.java
+++ b/media/java/android/media/AmrInputStream.java
@@ -44,7 +44,7 @@ public final class AmrInputStream extends InputStream
private int mGae;
// result amr stream
- private byte[] mBuf = new byte[SAMPLES_PER_FRAME * 2];
+ private final byte[] mBuf = new byte[SAMPLES_PER_FRAME * 2];
private int mBufIn = 0;
private int mBufOut = 0;
diff --git a/media/java/android/media/AsyncPlayer.java b/media/java/android/media/AsyncPlayer.java
index 09aec2e..804528e 100644
--- a/media/java/android/media/AsyncPlayer.java
+++ b/media/java/android/media/AsyncPlayer.java
@@ -49,7 +49,7 @@ public class AsyncPlayer {
}
}
- private LinkedList<Command> mCmdQueue = new LinkedList();
+ private final LinkedList<Command> mCmdQueue = new LinkedList();
private void startSound(Command cmd) {
// Preparing can be slow, so if there is something else
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 936ec0f..78eb89f 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1509,7 +1509,7 @@ public class AudioManager {
* Map to convert focus event listener IDs, as used in the AudioService audio focus stack,
* to actual listener objects.
*/
- private HashMap<String, OnAudioFocusChangeListener> mAudioFocusIdListenerMap =
+ private final HashMap<String, OnAudioFocusChangeListener> mAudioFocusIdListenerMap =
new HashMap<String, OnAudioFocusChangeListener>();
/**
* Lock to prevent concurrent changes to the list of focus listeners for this AudioManager
@@ -1524,7 +1524,7 @@ public class AudioManager {
/**
* Handler for audio focus events coming from the audio service.
*/
- private FocusEventHandlerDelegate mAudioFocusEventHandlerDelegate =
+ private final FocusEventHandlerDelegate mAudioFocusEventHandlerDelegate =
new FocusEventHandlerDelegate();
/**
@@ -1563,7 +1563,7 @@ public class AudioManager {
}
}
- private IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() {
+ private final IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() {
public void dispatchAudioFocusChange(int focusChange, String id) {
Message m = mAudioFocusEventHandlerDelegate.getHandler().obtainMessage(focusChange, id);
@@ -1649,11 +1649,46 @@ public class AudioManager {
mAudioFocusDispatcher, getIdForAudioFocusListener(l),
mContext.getPackageName() /* package name */);
} catch (RemoteException e) {
- Log.e(TAG, "Can't call requestAudioFocus() from AudioService due to "+e);
+ Log.e(TAG, "Can't call requestAudioFocus() on AudioService due to "+e);
}
return status;
}
+ /**
+ * @hide
+ * Used internally by telephony package to request audio focus. Will cause the focus request
+ * to be associated with the "voice communication" identifier only used in AudioService
+ * to identify this use case.
+ * @param streamType use STREAM_RING for focus requests when ringing, VOICE_CALL for
+ * the establishment of the call
+ * @param durationHint the type of focus request. AUDIOFOCUS_GAIN_TRANSIENT is recommended so
+ * media applications resume after a call
+ */
+ public void requestAudioFocusForCall(int streamType, int durationHint) {
+ IAudioService service = getService();
+ try {
+ service.requestAudioFocus(streamType, durationHint, mICallBack, null,
+ AudioService.IN_VOICE_COMM_FOCUS_ID,
+ "system" /* dump-friendly package name */);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Can't call requestAudioFocusForCall() on AudioService due to "+e);
+ }
+ }
+
+ /**
+ * @hide
+ * Used internally by telephony package to abandon audio focus, typically after a call or
+ * when ringing ends and the call is rejected or not answered.
+ * Should match one or more calls to {@link #requestAudioFocusForCall(int, int)}.
+ */
+ public void abandonAudioFocusForCall() {
+ IAudioService service = getService();
+ try {
+ service.abandonAudioFocus(null, AudioService.IN_VOICE_COMM_FOCUS_ID);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Can't call abandonAudioFocusForCall() on AudioService due to "+e);
+ }
+ }
/**
* Abandon audio focus. Causes the previous focus owner, if any, to receive focus.
@@ -1668,7 +1703,7 @@ public class AudioManager {
status = service.abandonAudioFocus(mAudioFocusDispatcher,
getIdForAudioFocusListener(l));
} catch (RemoteException e) {
- Log.e(TAG, "Can't call abandonAudioFocus() from AudioService due to "+e);
+ Log.e(TAG, "Can't call abandonAudioFocus() on AudioService due to "+e);
}
return status;
}
@@ -1920,7 +1955,7 @@ public class AudioManager {
/**
* {@hide}
*/
- private IBinder mICallBack = new Binder();
+ private final IBinder mICallBack = new Binder();
/**
* Checks whether the phone is in silent mode, with or without vibrate.
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 855e831..5cc24c0 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -161,7 +161,7 @@ public class AudioRecord
/**
* Lock to make sure mRecordingState updates are reflecting the actual state of the object.
*/
- private Object mRecordingStateLock = new Object();
+ private final Object mRecordingStateLock = new Object();
/**
* The listener the AudioRecord notifies when the record position reaches a marker
* or for periodic updates during the progression of the record head.
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 2eafd68..13e3982 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -151,7 +151,7 @@ public class AudioService extends IAudioService.Stub {
private boolean mMediaServerOk;
private SoundPool mSoundPool;
- private Object mSoundEffectsLock = new Object();
+ private final Object mSoundEffectsLock = new Object();
private static final int NUM_SOUNDPOOL_CHANNELS = 4;
private static final int SOUND_EFFECT_VOLUME = 1000;
@@ -168,7 +168,7 @@ public class AudioService extends IAudioService.Stub {
/* Sound effect file name mapping sound effect id (AudioManager.FX_xxx) to
* file index in SOUND_EFFECT_FILES[] (first column) and indicating if effect
* uses soundpool (second column) */
- private int[][] SOUND_EFFECT_FILES_MAP = new int[][] {
+ private final int[][] SOUND_EFFECT_FILES_MAP = new int[][] {
{0, -1}, // FX_KEY_CLICK
{0, -1}, // FX_FOCUS_NAVIGATION_UP
{0, -1}, // FX_FOCUS_NAVIGATION_DOWN
@@ -181,7 +181,7 @@ public class AudioService extends IAudioService.Stub {
};
/** @hide Maximum volume index values for audio streams */
- private int[] MAX_STREAM_VOLUME = new int[] {
+ private final int[] MAX_STREAM_VOLUME = new int[] {
5, // STREAM_VOICE_CALL
7, // STREAM_SYSTEM
7, // STREAM_RING
@@ -197,7 +197,7 @@ public class AudioService extends IAudioService.Stub {
* of another stream: This avoids multiplying the volume settings for hidden
* stream types that follow other stream behavior for volume settings
* NOTE: do not create loops in aliases! */
- private int[] STREAM_VOLUME_ALIAS = new int[] {
+ private final int[] STREAM_VOLUME_ALIAS = new int[] {
AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL
AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM
AudioSystem.STREAM_RING, // STREAM_RING
@@ -210,7 +210,7 @@ public class AudioService extends IAudioService.Stub {
AudioSystem.STREAM_MUSIC // STREAM_TTS
};
- private AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
+ private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
public void onError(int error) {
switch (error) {
case AudioSystem.AUDIO_STATUS_SERVER_DIED:
@@ -270,17 +270,17 @@ public class AudioService extends IAudioService.Stub {
private boolean mIsRinging = false;
// Devices currently connected
- private HashMap <Integer, String> mConnectedDevices = new HashMap <Integer, String>();
+ private final HashMap <Integer, String> mConnectedDevices = new HashMap <Integer, String>();
// Forced device usage for communications
private int mForcedUseForComm;
// List of binder death handlers for setMode() client processes.
// The last process to have called setMode() is at the top of the list.
- private ArrayList <SetModeDeathHandler> mSetModeDeathHandlers = new ArrayList <SetModeDeathHandler>();
+ private final ArrayList <SetModeDeathHandler> mSetModeDeathHandlers = new ArrayList <SetModeDeathHandler>();
// List of clients having issued a SCO start request
- private ArrayList <ScoClient> mScoClients = new ArrayList <ScoClient>();
+ private final ArrayList <ScoClient> mScoClients = new ArrayList <ScoClient>();
// BluetoothHeadset API to control SCO connection
private BluetoothHeadset mBluetoothHeadset;
@@ -992,8 +992,6 @@ public class AudioService extends IAudioService.Stub {
if (mode != mMode) {
status = AudioSystem.setPhoneState(mode);
if (status == AudioSystem.AUDIO_STATUS_OK) {
- // automatically handle audio focus for mode changes
- handleFocusForCalls(mMode, mode, cb);
mMode = mode;
} else {
if (hdlr != null) {
@@ -1024,40 +1022,6 @@ public class AudioService extends IAudioService.Stub {
return newModeOwnerPid;
}
- /** pre-condition: oldMode != newMode */
- private void handleFocusForCalls(int oldMode, int newMode, IBinder cb) {
- // if ringing
- if (newMode == AudioSystem.MODE_RINGTONE) {
- // if not ringing silently
- int ringVolume = AudioService.this.getStreamVolume(AudioManager.STREAM_RING);
- if (ringVolume > 0) {
- // request audio focus for the communication focus entry
- requestAudioFocus(AudioManager.STREAM_RING,
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, cb,
- null /* IAudioFocusDispatcher allowed to be null only for this clientId */,
- IN_VOICE_COMM_FOCUS_ID /*clientId*/,
- "system");
-
- }
- }
- // if entering call
- else if ((newMode == AudioSystem.MODE_IN_CALL)
- || (newMode == AudioSystem.MODE_IN_COMMUNICATION)) {
- // request audio focus for the communication focus entry
- // (it's ok if focus was already requested during ringing)
- requestAudioFocus(AudioManager.STREAM_RING,
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, cb,
- null /* IAudioFocusDispatcher allowed to be null only for this clientId */,
- IN_VOICE_COMM_FOCUS_ID /*clientId*/,
- "system");
- }
- // if exiting call
- else if (newMode == AudioSystem.MODE_NORMAL) {
- // abandon audio focus for communication focus entry
- abandonAudioFocus(null, IN_VOICE_COMM_FOCUS_ID);
- }
- }
-
/** @see AudioManager#getMode() */
public int getMode() {
return mMode;
@@ -2896,9 +2860,10 @@ public class AudioService extends IAudioService.Stub {
//==========================================================================================
/* constant to identify focus stack entry that is used to hold the focus while the phone
- * is ringing or during a call
+ * is ringing or during a call. Used by com.android.internal.telephony.CallManager when
+ * entering and exiting calls.
*/
- private final static String IN_VOICE_COMM_FOCUS_ID = "AudioFocus_For_Phone_Ring_And_Calls";
+ public final static String IN_VOICE_COMM_FOCUS_ID = "AudioFocus_For_Phone_Ring_And_Calls";
private final static Object mAudioFocusLock = new Object();
@@ -2980,7 +2945,7 @@ public class AudioService extends IAudioService.Stub {
}
}
- private Stack<FocusStackEntry> mFocusStack = new Stack<FocusStackEntry>();
+ private final Stack<FocusStackEntry> mFocusStack = new Stack<FocusStackEntry>();
/**
* Helper function:
@@ -3357,7 +3322,7 @@ public class AudioService extends IAudioService.Stub {
* synchronized on mRCStack, but also BEFORE on mFocusLock as any change in either
* stack, audio focus or RC, can lead to a change in the remote control display
*/
- private Stack<RemoteControlStackEntry> mRCStack = new Stack<RemoteControlStackEntry>();
+ private final Stack<RemoteControlStackEntry> mRCStack = new Stack<RemoteControlStackEntry>();
/**
* Helper function:
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 925f965..9d6c9f6 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -111,7 +111,7 @@ public class ExifInterface {
// there can only be one user at a time for the native functions (and
// they cannot keep state in the native code across function calls). We
// use sLock to serialize the accesses.
- private static Object sLock = new Object();
+ private static final Object sLock = new Object();
/**
* Reads Exif tags from the specified JPEG file.
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index e275aa6..7f7e284 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -120,18 +120,18 @@ public class MediaFile {
}
}
- private static HashMap<String, MediaFileType> sFileTypeMap
+ private static final HashMap<String, MediaFileType> sFileTypeMap
= new HashMap<String, MediaFileType>();
- private static HashMap<String, Integer> sMimeTypeMap
+ private static final HashMap<String, Integer> sMimeTypeMap
= new HashMap<String, Integer>();
// maps file extension to MTP format code
- private static HashMap<String, Integer> sFileTypeToFormatMap
+ private static final HashMap<String, Integer> sFileTypeToFormatMap
= new HashMap<String, Integer>();
// maps mime type to MTP format code
- private static HashMap<String, Integer> sMimeTypeToFormatMap
+ private static final HashMap<String, Integer> sMimeTypeToFormatMap
= new HashMap<String, Integer>();
// maps MTP format code to mime type
- private static HashMap<Integer, String> sFormatToMimeTypeMap
+ private static final HashMap<Integer, String> sFormatToMimeTypeMap
= new HashMap<Integer, String>();
static void addFileType(String extension, int fileType, String mimeType) {
diff --git a/media/java/android/media/MediaInserter.java b/media/java/android/media/MediaInserter.java
index a998407..e92c710 100644
--- a/media/java/android/media/MediaInserter.java
+++ b/media/java/android/media/MediaInserter.java
@@ -32,7 +32,7 @@ import java.util.List;
* {@hide}
*/
public class MediaInserter {
- private HashMap<Uri, List<ContentValues>> mRowMap =
+ private final HashMap<Uri, List<ContentValues>> mRowMap =
new HashMap<Uri, List<ContentValues>>();
private IContentProvider mProvider;
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 08e6032..85d99c1 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -138,10 +138,13 @@ public class MediaRecorder
*/
public final class AudioSource {
/* Do not change these values without updating their counterparts
- * in include/media/mediarecorder.h!
+ * in system/core/include/system/audio.h!
*/
private AudioSource() {}
+
+ /** Default audio source **/
public static final int DEFAULT = 0;
+
/** Microphone audio source */
public static final int MIC = 1;
@@ -201,18 +204,24 @@ public class MediaRecorder
/** MPEG4 media file format*/
public static final int MPEG_4 = 2;
- /** The following formats are audio only .aac or .amr formats **/
- /** @deprecated Deprecated in favor of AMR_NB */
- /** Deprecated in favor of MediaRecorder.OutputFormat.AMR_NB */
- /** AMR NB file format */
+ /** The following formats are audio only .aac or .amr formats */
+
+ /**
+ * AMR NB file format
+ * @deprecated Deprecated in favor of MediaRecorder.OutputFormat.AMR_NB
+ */
public static final int RAW_AMR = 3;
+
/** AMR NB file format */
public static final int AMR_NB = 3;
+
/** AMR WB file format */
public static final int AMR_WB = 4;
+
/** @hide AAC ADIF file format */
public static final int AAC_ADIF = 5;
- /** @hide AAC ADTS file format */
+
+ /** AAC ADTS file format */
public static final int AAC_ADTS = 6;
/** @hide Stream over a socket, limited to a single stream */
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index b06ef95..1c13fff 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -35,6 +35,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.provider.MediaStore;
+import android.provider.MediaStore.Files.FileColumns;
import android.provider.Settings;
import android.provider.MediaStore.Audio;
import android.provider.MediaStore.Files;
@@ -58,6 +59,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Locale;
/**
* Internal service helper that no-one should use directly.
@@ -312,10 +314,8 @@ public class MediaScanner
private final String mExternalStoragePath;
- // WARNING: Bulk inserts sounded like a great idea and gave us a good performance improvement,
- // but unfortunately it also introduced a number of bugs. All the known bugs were fixed,
- // but we need more testing before enabling.
- private static final boolean ENABLE_BULK_INSERTS = false;
+ /** whether to use bulk inserts or individual inserts for each item */
+ private static final boolean ENABLE_BULK_INSERTS = true;
// used when scanning the image database so we know whether we have to prune
// old thumbnail files
@@ -345,7 +345,7 @@ public class MediaScanner
// this should be set when scanning files on a case insensitive file system.
private boolean mCaseInsensitivePaths;
- private BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
+ private final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
private static class FileCacheEntry {
long mRowId;
@@ -401,7 +401,7 @@ public class MediaScanner
+ Settings.System.ALARM_ALERT);
}
- private MyMediaScannerClient mClient = new MyMediaScannerClient();
+ private final MyMediaScannerClient mClient = new MyMediaScannerClient();
private boolean isDrmEnabled() {
String prop = SystemProperties.get("drm.service.enabled");
@@ -946,6 +946,22 @@ public class MediaScanner
// path should never change, and we want to avoid replacing mixed cased paths
// with squashed lower case paths
values.remove(MediaStore.MediaColumns.DATA);
+
+ int mediaType = 0;
+ if (!MediaScanner.isNoMediaPath(entry.mPath)) {
+ int fileType = MediaFile.getFileTypeForMimeType(mMimeType);
+ if (MediaFile.isAudioFileType(fileType)) {
+ mediaType = FileColumns.MEDIA_TYPE_AUDIO;
+ } else if (MediaFile.isVideoFileType(fileType)) {
+ mediaType = FileColumns.MEDIA_TYPE_VIDEO;
+ } else if (MediaFile.isImageFileType(fileType)) {
+ mediaType = FileColumns.MEDIA_TYPE_IMAGE;
+ } else if (MediaFile.isPlayListFileType(fileType)) {
+ mediaType = FileColumns.MEDIA_TYPE_PLAYLIST;
+ }
+ values.put(FileColumns.MEDIA_TYPE, mediaType);
+ }
+
mMediaProvider.update(result, values, null, null);
}
@@ -1035,7 +1051,7 @@ public class MediaScanner
// First read existing files from the files table
c = mMediaProvider.query(mFilesUri, FILES_PRESCAN_PROJECTION,
- where, selectionArgs, null);
+ where, selectionArgs, null, null);
if (c != null) {
mWasEmptyPriorToScan = c.getCount() == 0;
@@ -1072,7 +1088,7 @@ public class MediaScanner
// compute original size of images
mOriginalCount = 0;
- c = mMediaProvider.query(mImagesUri, ID_PROJECTION, null, null, null);
+ c = mMediaProvider.query(mImagesUri, ID_PROJECTION, null, null, null, null);
if (c != null) {
mOriginalCount = c.getCount();
c.close();
@@ -1107,7 +1123,7 @@ public class MediaScanner
new String [] { "_data" },
null,
null,
- null);
+ null, null);
Log.v(TAG, "pruneDeadThumbnailFiles... " + c);
if (c != null && c.moveToFirst()) {
do {
@@ -1180,6 +1196,10 @@ public class MediaScanner
mMediaProvider.delete(ContentUris.withAppendedId(mFilesUri, entry.mRowId),
null, null);
iterator.remove();
+ if (entry.mPath.toLowerCase(Locale.US).endsWith("/.nomedia")) {
+ File f = new File(path);
+ mMediaProvider.call(MediaStore.UNHIDE_CALL, f.getParent(), null);
+ }
}
}
}
@@ -1472,7 +1492,7 @@ public class MediaScanner
if (bestMatch.mRowId == 0) {
Cursor c = mMediaProvider.query(mAudioUri, ID_PROJECTION,
MediaStore.Files.FileColumns.DATA + "=?",
- new String[] { bestMatch.mPath }, null);
+ new String[] { bestMatch.mPath }, null, null);
if (c != null) {
if (c.moveToNext()) {
bestMatch.mRowId = c.getLong(0);
diff --git a/media/java/android/media/MediaScannerConnection.java b/media/java/android/media/MediaScannerConnection.java
index 969da39..21b6e14 100644
--- a/media/java/android/media/MediaScannerConnection.java
+++ b/media/java/android/media/MediaScannerConnection.java
@@ -46,7 +46,7 @@ public class MediaScannerConnection implements ServiceConnection {
private IMediaScannerService mService;
private boolean mConnected; // true if connect() has been called since last disconnect()
- private IMediaScannerListener.Stub mListener = new IMediaScannerListener.Stub() {
+ private final IMediaScannerListener.Stub mListener = new IMediaScannerListener.Stub() {
public void scanCompleted(String path, Uri uri) {
MediaScannerConnectionClient client = mClient;
if (client != null) {
diff --git a/media/java/android/media/MiniThumbFile.java b/media/java/android/media/MiniThumbFile.java
index df141c1..63b149c 100644
--- a/media/java/android/media/MiniThumbFile.java
+++ b/media/java/android/media/MiniThumbFile.java
@@ -52,7 +52,7 @@ public class MiniThumbFile {
private RandomAccessFile mMiniThumbFile;
private FileChannel mChannel;
private ByteBuffer mBuffer;
- private static Hashtable<String, MiniThumbFile> sThumbFiles =
+ private static final Hashtable<String, MiniThumbFile> sThumbFiles =
new Hashtable<String, MiniThumbFile>();
/**
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 77acfe6..18b4ee6 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -576,6 +576,7 @@ public class RemoteControlClient
/**
* Cache for the metadata strings.
* Access synchronized on mCacheLock
+ * This is re-initialized in apply() and so cannot be final.
*/
private Bundle mMetadata = new Bundle();
@@ -621,7 +622,7 @@ public class RemoteControlClient
/**
* The IRemoteControlClient implementation
*/
- private IRemoteControlClient mIRCC = new IRemoteControlClient.Stub() {
+ private final IRemoteControlClient mIRCC = new IRemoteControlClient.Stub() {
public void onInformationRequested(int clientGeneration, int infoFlags,
int artWidth, int artHeight) {
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 9c0819f..7aaf4aa 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -224,7 +224,7 @@ public class RingtoneManager {
* If a column (item from this list) exists in the Cursor, its value must
* be true (value of 1) for the row to be returned.
*/
- private List<String> mFilterColumns = new ArrayList<String>();
+ private final List<String> mFilterColumns = new ArrayList<String>();
private boolean mStopPreviousRingtone = true;
private Ringtone mPreviousRingtone;
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 19db1c0..18aa4b3 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -266,7 +266,7 @@ public class MtpDatabase {
Cursor c = null;
try {
c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, PATH_WHERE,
- new String[] { path }, null);
+ new String[] { path }, null, null);
if (c != null && c.getCount() > 0) {
Log.w(TAG, "file already exists in beginSendObject: " + path);
return -1;
@@ -433,7 +433,7 @@ public class MtpDatabase {
}
}
- return mMediaProvider.query(mObjectsUri, ID_PROJECTION, where, whereArgs, null);
+ return mMediaProvider.query(mObjectsUri, ID_PROJECTION, where, whereArgs, null, null);
}
private int[] getObjectList(int storageID, int format, int parent) {
@@ -699,7 +699,7 @@ public class MtpDatabase {
String path = null;
String[] whereArgs = new String[] { Integer.toString(handle) };
try {
- c = mMediaProvider.query(mObjectsUri, PATH_PROJECTION, ID_WHERE, whereArgs, null);
+ c = mMediaProvider.query(mObjectsUri, PATH_PROJECTION, ID_WHERE, whereArgs, null, null);
if (c != null && c.moveToNext()) {
path = c.getString(1);
}
@@ -752,6 +752,29 @@ public class MtpDatabase {
return MtpConstants.RESPONSE_GENERAL_ERROR;
}
+ // check if nomedia status changed
+ if (newFile.isDirectory()) {
+ // for directories, check if renamed from something hidden to something non-hidden
+ if (oldFile.getName().startsWith(".") && !newPath.startsWith(".")) {
+ // directory was unhidden
+ try {
+ mMediaProvider.call(MediaStore.UNHIDE_CALL, newPath, null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to unhide/rescan for " + newPath);
+ }
+ }
+ } else {
+ // for files, check if renamed from .nomedia to something else
+ if (oldFile.getName().toLowerCase(Locale.US).equals(".nomedia")
+ && !newPath.toLowerCase(Locale.US).equals(".nomedia")) {
+ try {
+ mMediaProvider.call(MediaStore.UNHIDE_CALL, oldFile.getParent(), null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to unhide/rescan for " + newPath);
+ }
+ }
+ }
+
return MtpConstants.RESPONSE_OK;
}
@@ -815,7 +838,7 @@ public class MtpDatabase {
Cursor c = null;
try {
c = mMediaProvider.query(mObjectsUri, OBJECT_INFO_PROJECTION,
- ID_WHERE, new String[] { Integer.toString(handle) }, null);
+ ID_WHERE, new String[] { Integer.toString(handle) }, null, null);
if (c != null && c.moveToNext()) {
outStorageFormatParent[0] = c.getInt(1);
outStorageFormatParent[1] = c.getInt(2);
@@ -858,7 +881,7 @@ public class MtpDatabase {
Cursor c = null;
try {
c = mMediaProvider.query(mObjectsUri, PATH_SIZE_FORMAT_PROJECTION,
- ID_WHERE, new String[] { Integer.toString(handle) }, null);
+ ID_WHERE, new String[] { Integer.toString(handle) }, null, null);
if (c != null && c.moveToNext()) {
String path = c.getString(1);
path.getChars(0, path.length(), outFilePath, 0);
@@ -887,7 +910,7 @@ public class MtpDatabase {
Cursor c = null;
try {
c = mMediaProvider.query(mObjectsUri, PATH_SIZE_FORMAT_PROJECTION,
- ID_WHERE, new String[] { Integer.toString(handle) }, null);
+ ID_WHERE, new String[] { Integer.toString(handle) }, null, null);
if (c != null && c.moveToNext()) {
// don't convert to media path here, since we will be matching
// against paths in the database matching /data/media
@@ -915,6 +938,15 @@ public class MtpDatabase {
Uri uri = Files.getMtpObjectsUri(mVolumeName, handle);
if (mMediaProvider.delete(uri, null, null) > 0) {
+ if (format != MtpConstants.FORMAT_ASSOCIATION
+ && path.toLowerCase(Locale.US).endsWith("/.nomedia")) {
+ try {
+ String parentPath = path.substring(0, path.lastIndexOf("/"));
+ mMediaProvider.call(MediaStore.UNHIDE_CALL, parentPath, null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to unhide/rescan for " + path);
+ }
+ }
return MtpConstants.RESPONSE_OK;
} else {
return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
@@ -933,7 +965,7 @@ public class MtpDatabase {
Uri uri = Files.getMtpReferencesUri(mVolumeName, handle);
Cursor c = null;
try {
- c = mMediaProvider.query(uri, ID_PROJECTION, null, null, null);
+ c = mMediaProvider.query(uri, ID_PROJECTION, null, null, null, null);
if (c == null) {
return null;
}
diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java
index 76c8569..dab5454 100644
--- a/media/java/android/mtp/MtpPropertyGroup.java
+++ b/media/java/android/mtp/MtpPropertyGroup.java
@@ -191,7 +191,7 @@ class MtpPropertyGroup {
// for now we are only reading properties from the "objects" table
c = mProvider.query(mUri,
new String [] { Files.FileColumns._ID, column },
- ID_WHERE, new String[] { Integer.toString(id) }, null);
+ ID_WHERE, new String[] { Integer.toString(id) }, null, null);
if (c != null && c.moveToNext()) {
return c.getString(1);
} else {
@@ -211,7 +211,7 @@ class MtpPropertyGroup {
try {
c = mProvider.query(Audio.Media.getContentUri(mVolumeName),
new String [] { Files.FileColumns._ID, column },
- ID_WHERE, new String[] { Integer.toString(id) }, null);
+ ID_WHERE, new String[] { Integer.toString(id) }, null, null);
if (c != null && c.moveToNext()) {
return c.getString(1);
} else {
@@ -232,7 +232,7 @@ class MtpPropertyGroup {
Uri uri = Audio.Genres.getContentUriForAudioId(mVolumeName, id);
c = mProvider.query(uri,
new String [] { Files.FileColumns._ID, Audio.GenresColumns.NAME },
- null, null, null);
+ null, null, null, null);
if (c != null && c.moveToNext()) {
return c.getString(1);
} else {
@@ -254,7 +254,7 @@ class MtpPropertyGroup {
// for now we are only reading properties from the "objects" table
c = mProvider.query(mUri,
new String [] { Files.FileColumns._ID, column },
- ID_WHERE, new String[] { Integer.toString(id) }, null);
+ ID_WHERE, new String[] { Integer.toString(id) }, null, null);
if (c != null && c.moveToNext()) {
return new Long(c.getLong(1));
}
@@ -323,7 +323,7 @@ class MtpPropertyGroup {
try {
// don't query if not necessary
if (depth > 0 || handle == 0xFFFFFFFF || mColumns.length > 1) {
- c = mProvider.query(mUri, mColumns, where, whereArgs, null);
+ c = mProvider.query(mUri, mColumns, where, whereArgs, null, null);
if (c == null) {
return new MtpPropertyList(0, MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
}