Merge "Add an auto-exposure lock feature to the Camera API."
diff --git a/include/drm/drm_framework_common.h b/include/drm/drm_framework_common.h
index d2d1d7e..3330ebc 100644
--- a/include/drm/drm_framework_common.h
+++ b/include/drm/drm_framework_common.h
@@ -31,14 +31,17 @@
  * Error code for DRM Frameowrk
  */
 enum {
-    DRM_ERROR_BASE = -2000,
+    // The following constant values should be in sync with
+    // media/stagefright/MediaErrors.h
+    ERROR_BASE = -2000,
 
-    DRM_ERROR_UNKNOWN                       = DRM_ERROR_BASE,
-    DRM_ERROR_LICENSE_EXPIRED               = DRM_ERROR_BASE - 1,
-    DRM_ERROR_SESSION_NOT_OPENED            = DRM_ERROR_BASE - 2,
-    DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED  = DRM_ERROR_BASE - 3,
-    DRM_ERROR_DECRYPT                       = DRM_ERROR_BASE - 4,
-    DRM_ERROR_CANNOT_HANDLE                 = DRM_ERROR_BASE - 5,
+    DRM_ERROR_UNKNOWN                       = ERROR_BASE,
+    DRM_ERROR_NO_LICENSE                    = ERROR_BASE - 1,
+    DRM_ERROR_LICENSE_EXPIRED               = ERROR_BASE - 2,
+    DRM_ERROR_SESSION_NOT_OPENED            = ERROR_BASE - 3,
+    DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED  = ERROR_BASE - 4,
+    DRM_ERROR_DECRYPT                       = ERROR_BASE - 5,
+    DRM_ERROR_CANNOT_HANDLE                 = ERROR_BASE - 6,
 
     DRM_NO_ERROR                            = NO_ERROR
 };
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index 9b1af6b..d552b2e 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -51,6 +51,8 @@
     virtual status_t        setVolume(float leftVolume, float rightVolume) = 0;
     virtual status_t        setAuxEffectSendLevel(float level) = 0;
     virtual status_t        attachAuxEffect(int effectId) = 0;
+    virtual status_t        setParameter(int key, const Parcel& request) = 0;
+    virtual status_t        getParameter(int key, Parcel* reply) = 0;
 
     // Invoke a generic method on the player by using opaque parcels
     // for the request and reply.
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index bebecc0..f0401cc 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -132,6 +132,8 @@
     virtual status_t    reset() = 0;
     virtual status_t    setLooping(int loop) = 0;
     virtual player_type playerType() = 0;
+    virtual status_t    setParameter(int key, const Parcel &request) = 0;
+    virtual status_t    getParameter(int key, Parcel *reply) = 0;
 
     // Invoke a generic method on the player by using opaque parcels
     // for the request and reply.
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 748e489..241626c 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -177,6 +177,9 @@
             int             getAudioSessionId();
             status_t        setAuxEffectSendLevel(float level);
             status_t        attachAuxEffect(int effectId);
+            status_t        setParameter(int key, const Parcel& request);
+            status_t        getParameter(int key, Parcel* reply);
+
 private:
             void            clear_l();
             status_t        seekTo_l(int msec);
diff --git a/include/media/stagefright/MediaErrors.h b/include/media/stagefright/MediaErrors.h
index 1a6d548..7cc993c 100644
--- a/include/media/stagefright/MediaErrors.h
+++ b/include/media/stagefright/MediaErrors.h
@@ -41,7 +41,17 @@
     INFO_FORMAT_CHANGED    = MEDIA_ERROR_BASE - 12,
     INFO_DISCONTINUITY     = MEDIA_ERROR_BASE - 13,
 
-    ERROR_NO_LICENSE       = MEDIA_ERROR_BASE - 14,
+    // The following constant values should be in sync with
+    // drm/drm_framework_common.h
+    DRM_ERROR_BASE = -2000,
+
+    ERROR_DRM_UNKNOWN                       = DRM_ERROR_BASE,
+    ERROR_DRM_NO_LICENSE                    = DRM_ERROR_BASE - 1,
+    ERROR_DRM_LICENSE_EXPIRED               = DRM_ERROR_BASE - 2,
+    ERROR_DRM_SESSION_NOT_OPENED            = DRM_ERROR_BASE - 3,
+    ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED  = DRM_ERROR_BASE - 4,
+    ERROR_DRM_DECRYPT                       = DRM_ERROR_BASE - 5,
+    ERROR_DRM_CANNOT_HANDLE                 = DRM_ERROR_BASE - 6,
 
     // Heartbeat Error Codes
     HEARTBEAT_ERROR_BASE = -3000,
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h
index c7db9a6..6b1fa77 100644
--- a/include/private/opengles/gl_context.h
+++ b/include/private/opengles/gl_context.h
@@ -26,14 +26,11 @@
 #endif
 
 #include <private/pixelflinger/ggl_context.h>
-#include <hardware/copybit.h>
 #include <hardware/gralloc.h>
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
-struct android_native_buffer_t;
-
 namespace android {
 
 
@@ -604,14 +601,6 @@
     void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
 };
 
-struct copybits_context_t {
-    // A handle to the blit engine, if it exists, else NULL.
-    copybit_device_t*       blitEngine;
-    int32_t                 minScale;
-    int32_t                 maxScale;
-    android_native_buffer_t* drawSurfaceBuffer;
-};
-
 struct ogles_context_t {
     context_t               rasterizer;
     array_machine_t         arrays         __attribute__((aligned(32)));
@@ -636,13 +625,6 @@
     EGLSurfaceManager*      surfaceManager;
     EGLBufferObjectManager* bufferObjectManager;
 
-    // copybits is only used if LIBAGL_USE_GRALLOC_COPYBITS is
-    // defined, but it is always present because ogles_context_t is a public
-    // struct that is used by clients of libagl. We want the size and offsets
-    // to stay the same, whether or not LIBAGL_USE_GRALLOC_COPYBITS is defined.
-
-    copybits_context_t      copybits;
-
     GLenum                  error;
 
     static inline ogles_context_t* get() {
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 8885bd5..76a8a91 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -48,6 +48,8 @@
     SET_AUX_EFFECT_SEND_LEVEL,
     ATTACH_AUX_EFFECT,
     SET_VIDEO_SURFACETEXTURE,
+    SET_PARAMETER,
+    GET_PARAMETER,
 };
 
 class BpMediaPlayer: public BpInterface<IMediaPlayer>
@@ -236,6 +238,26 @@
         return reply.readInt32();
     }
 
+    status_t setParameter(int key, const Parcel& request)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+        data.writeInt32(key);
+        if (request.dataSize() > 0) {
+            data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
+        }
+        remote()->transact(SET_PARAMETER, data, &reply);
+        return reply.readInt32();
+    }
+
+    status_t getParameter(int key, Parcel *reply)
+    {
+        Parcel data;
+        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+        data.writeInt32(key);
+        return remote()->transact(GET_PARAMETER, data, reply);
+    }
+
 };
 
 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
@@ -361,6 +383,23 @@
             reply->writeInt32(attachAuxEffect(data.readInt32()));
             return NO_ERROR;
         } break;
+        case SET_PARAMETER: {
+            CHECK_INTERFACE(IMediaPlayer, data, reply);
+            int key = data.readInt32();
+
+            Parcel request;
+            if (data.dataAvail() > 0) {
+                request.appendFrom(
+                        const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
+            }
+            request.setDataPosition(0);
+            reply->writeInt32(setParameter(key, request));
+            return NO_ERROR;
+        } break;
+        case GET_PARAMETER: {
+            CHECK_INTERFACE(IMediaPlayer, data, reply);
+            return getParameter(data.readInt32(), reply);
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index 4e22175..28c8642 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -135,20 +135,21 @@
         }
         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] == '.')
-                    noMedia = true;
+                    childNoMedia = true;
 
                 // report the directory to the client
                 if (stat(path, &statbuf) == 0) {
-                    client.scanFile(path, statbuf.st_mtime, 0, true, noMedia);
+                    client.scanFile(path, statbuf.st_mtime, 0, true, childNoMedia);
                 }
 
                 // and now process its contents
                 strcat(fileSpot, "/");
                 int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client,
-                        noMedia, exceptionCheck, exceptionEnv);
+                        childNoMedia, exceptionCheck, exceptionEnv);
                 if (err) {
                     // pass exceptions up - ignore other errors
                     if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure;
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 9daa80f..28e07ff 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -553,6 +553,28 @@
     return mPlayer->attachAuxEffect(effectId);
 }
 
+status_t MediaPlayer::setParameter(int key, const Parcel& request)
+{
+    LOGV("MediaPlayer::setParameter(%d)", key);
+    Mutex::Autolock _l(mLock);
+    if (mPlayer != NULL) {
+        return  mPlayer->setParameter(key, request);
+    }
+    LOGV("setParameter: no active player");
+    return INVALID_OPERATION;
+}
+
+status_t MediaPlayer::getParameter(int key, Parcel *reply)
+{
+    LOGV("MediaPlayer::getParameter(%d)", key);
+    Mutex::Autolock _l(mLock);
+    if (mPlayer != NULL) {
+         return  mPlayer->getParameter(key, reply);
+    }
+    LOGV("getParameter: no active player");
+    return INVALID_OPERATION;
+}
+
 void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj)
 {
     LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9dd353b..3b2cf10 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1024,6 +1024,20 @@
     return NO_ERROR;
 }
 
+status_t MediaPlayerService::Client::setParameter(int key, const Parcel &request) {
+    LOGV("[%d] setParameter(%d)", mConnId, key);
+    sp<MediaPlayerBase> p = getPlayer();
+    if (p == 0) return UNKNOWN_ERROR;
+    return p->setParameter(key, request);
+}
+
+status_t MediaPlayerService::Client::getParameter(int key, Parcel *reply) {
+    LOGV("[%d] getParameter(%d)", mConnId, key);
+    sp<MediaPlayerBase> p = getPlayer();
+    if (p == 0) return UNKNOWN_ERROR;
+    return p->getParameter(key, reply);
+}
+
 void MediaPlayerService::Client::notify(
         void* cookie, int msg, int ext1, int ext2, const Parcel *obj)
 {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 31b518e..6c4071f 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -279,6 +279,8 @@
                                             Parcel *reply);
         virtual status_t        setAuxEffectSendLevel(float level);
         virtual status_t        attachAuxEffect(int effectId);
+        virtual status_t        setParameter(int key, const Parcel &request);
+        virtual status_t        getParameter(int key, Parcel *reply);
 
         sp<MediaPlayerBase>     createPlayer(player_type playerType);
 
diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h
index a98231c..b35696f 100644
--- a/media/libmediaplayerservice/MidiFile.h
+++ b/media/libmediaplayerservice/MidiFile.h
@@ -55,6 +55,13 @@
     virtual status_t    invoke(const Parcel& request, Parcel *reply) {
         return INVALID_OPERATION;
     }
+    virtual status_t    setParameter(int key, const Parcel &request) {
+        return INVALID_OPERATION;
+    }
+    virtual status_t    getParameter(int key, Parcel *reply) {
+        return INVALID_OPERATION;
+    }
+
 
 private:
             status_t    createOutputTrack();
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index 6429395..02ec911 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -177,6 +177,16 @@
     mPlayer->setAudioSink(audioSink);
 }
 
+status_t StagefrightPlayer::setParameter(int key, const Parcel &request) {
+    LOGV("setParameter");
+    return mPlayer->setParameter(key, request);
+}
+
+status_t StagefrightPlayer::getParameter(int key, Parcel *reply) {
+    LOGV("getParameter");
+    return mPlayer->getParameter(key, reply);
+}
+
 status_t StagefrightPlayer::getMetadata(
         const media::Metadata::Filter& ids, Parcel *records) {
     using media::Metadata;
diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h
index e2796d2..ddd37e4 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.h
+++ b/media/libmediaplayerservice/StagefrightPlayer.h
@@ -55,6 +55,8 @@
     virtual player_type playerType();
     virtual status_t invoke(const Parcel &request, Parcel *reply);
     virtual void setAudioSink(const sp<AudioSink> &audioSink);
+    virtual status_t setParameter(int key, const Parcel &request);
+    virtual status_t getParameter(int key, Parcel *reply);
 
     virtual status_t getMetadata(
             const media::Metadata::Filter& ids, Parcel *records);
diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h
index d9c3db3..802a11b 100644
--- a/media/libmediaplayerservice/TestPlayerStub.h
+++ b/media/libmediaplayerservice/TestPlayerStub.h
@@ -99,6 +99,12 @@
     virtual status_t invoke(const android::Parcel& in, android::Parcel *out) {
         return mPlayer->invoke(in, out);
     }
+    virtual status_t setParameter(int key, const Parcel &request) {
+        return mPlayer->setParameter(key, request);
+    }
+    virtual status_t getParameter(int key, Parcel *reply) {
+        return mPlayer->getParameter(key, reply);
+    }
 
 
     // @return true if the current build is 'eng' or 'test' and the
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 0eca958..e1213f4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -246,6 +246,14 @@
     mPlayer->setAudioSink(audioSink);
 }
 
+status_t NuPlayerDriver::setParameter(int key, const Parcel &request) {
+    return INVALID_OPERATION;
+}
+
+status_t NuPlayerDriver::getParameter(int key, Parcel *reply) {
+    return INVALID_OPERATION;
+}
+
 status_t NuPlayerDriver::getMetadata(
         const media::Metadata::Filter& ids, Parcel *records) {
     return INVALID_OPERATION;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 67d0f3e..145fd80 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -52,6 +52,8 @@
     virtual player_type playerType();
     virtual status_t invoke(const Parcel &request, Parcel *reply);
     virtual void setAudioSink(const sp<AudioSink> &audioSink);
+    virtual status_t setParameter(int key, const Parcel &request);
+    virtual status_t getParameter(int key, Parcel *reply);
 
     virtual status_t getMetadata(
             const media::Metadata::Filter& ids, Parcel *records);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 1bfdd8e..974efa7 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -312,7 +312,7 @@
     if (mDecryptHandle != NULL) {
         CHECK(mDrmManagerClient);
         if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
-            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_NO_LICENSE);
+            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
         }
     }
 
@@ -1801,7 +1801,7 @@
     if (mDecryptHandle != NULL) {
         CHECK(mDrmManagerClient);
         if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
-            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_NO_LICENSE);
+            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
         }
     }
 
@@ -1905,4 +1905,11 @@
     postCheckAudioStatusEvent_l(0 /* delayUs */);
 }
 
+status_t AwesomePlayer::setParameter(int key, const Parcel &request) {
+    return OK;
+}
+
+status_t AwesomePlayer::getParameter(int key, Parcel *reply) {
+    return OK;
+}
 }  // namespace android
diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp
index c4ed516..1f3d581 100644
--- a/media/libstagefright/DRMExtractor.cpp
+++ b/media/libstagefright/DRMExtractor.cpp
@@ -146,18 +146,14 @@
     DrmBuffer *pDecryptedDrmBuffer = &decryptedDrmBuffer;
 
     if ((err = mDrmManagerClient->decrypt(mDecryptHandle, mTrackId,
-            &encryptedDrmBuffer, &pDecryptedDrmBuffer)) != DRM_NO_ERROR) {
+            &encryptedDrmBuffer, &pDecryptedDrmBuffer)) != NO_ERROR) {
 
         if (decryptedDrmBuffer.data) {
             delete [] decryptedDrmBuffer.data;
             decryptedDrmBuffer.data = NULL;
         }
 
-        if (err == DRM_ERROR_LICENSE_EXPIRED) {
-            return ERROR_NO_LICENSE;
-        } else {
-            return ERROR_IO;
-        }
+        return err;
     }
     CHECK(pDecryptedDrmBuffer == &decryptedDrmBuffer);
 
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 8c61064..2c17d92 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -88,6 +88,9 @@
     status_t getDuration(int64_t *durationUs);
     status_t getPosition(int64_t *positionUs);
 
+    status_t setParameter(int key, const Parcel &request);
+    status_t getParameter(int key, Parcel *reply);
+
     status_t seekTo(int64_t timeUs);
 
     // This is a mask of MediaExtractor::Flags.