Merge "NuPlayer: determine audio mode before instantiating audio decoder." into mnc-dev
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index a4b24d7..2ca3f1c 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -215,6 +215,7 @@
     sp<MemoryDealer> mDealer[2];
 
     sp<ANativeWindow> mNativeWindow;
+    int mNativeWindowUsageBits;
     sp<AMessage> mInputFormat;
     sp<AMessage> mOutputFormat;
     sp<AMessage> mBaseOutputFormat;
@@ -266,7 +267,8 @@
     status_t freeBuffer(OMX_U32 portIndex, size_t i);
 
     status_t handleSetSurface(const sp<Surface> &surface);
-    status_t setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */);
+    status_t setupNativeWindowSizeFormatAndUsage(
+            ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */);
 
     status_t configureOutputBuffersFromNativeWindow(
             OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk
index 20193c3..cc6f743 100644
--- a/media/libmediaplayerservice/nuplayer/Android.mk
+++ b/media/libmediaplayerservice/nuplayer/Android.mk
@@ -25,7 +25,8 @@
 	$(TOP)/frameworks/av/media/libmediaplayerservice              \
 	$(TOP)/frameworks/native/include/media/openmax
 
-LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CFLAGS += -Werror -Wall -DENABLE_STAGEFRIGHT_EXPERIMENTS
+
 LOCAL_CLANG := true
 
 LOCAL_MODULE:= libstagefright_nuplayer
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 26b83bb..3e0ee08 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -623,12 +623,19 @@
 
         case kWhatSetVideoSurface:
         {
-            ALOGV("kWhatSetVideoSurface");
 
             sp<RefBase> obj;
             CHECK(msg->findObject("surface", &obj));
             sp<Surface> surface = static_cast<Surface *>(obj.get());
-            if (mSource == NULL || mSource->getFormat(false /* audio */) == NULL) {
+
+            ALOGD("onSetVideoSurface(%p, %s video decoder)",
+                    surface.get(),
+                    (mSource != NULL && mSource->getFormat(false /* audio */) != NULL
+                            && mVideoDecoder != NULL) ? "have" : "no");
+
+            if (mSource == NULL || mSource->getFormat(false /* audio */) == NULL
+                    // NOTE: mVideoDecoder's mSurface is always non-null
+                    || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(surface) == OK)) {
                 performSetSurface(surface);
                 break;
             }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 99a2a84..dcc28c4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -87,6 +87,22 @@
     return mStats;
 }
 
+status_t NuPlayer::Decoder::setVideoSurface(const sp<Surface> &surface) {
+    if (surface == NULL || ADebug::isExperimentEnabled("legacy-setsurface")) {
+        return BAD_VALUE;
+    }
+
+    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
+
+    msg->setObject("surface", surface);
+    sp<AMessage> response;
+    status_t err = msg->postAndAwaitResponse(&response);
+    if (err == OK && response != NULL) {
+        CHECK(response->findInt32("err", &err));
+    }
+    return err;
+}
+
 void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
     ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
 
@@ -169,6 +185,46 @@
             break;
         }
 
+        case kWhatSetVideoSurface:
+        {
+            sp<AReplyToken> replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            sp<RefBase> obj;
+            CHECK(msg->findObject("surface", &obj));
+            sp<Surface> surface = static_cast<Surface *>(obj.get()); // non-null
+            int32_t err = INVALID_OPERATION;
+            // NOTE: in practice mSurface is always non-null, but checking here for completeness
+            if (mCodec != NULL && mSurface != NULL) {
+                // TODO: once AwesomePlayer is removed, remove this automatic connecting
+                // to the surface by MediaPlayerService.
+                //
+                // at this point MediaPlayerService::client has already connected to the
+                // surface, which MediaCodec does not expect
+                err = native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA);
+                if (err == OK) {
+                    err = mCodec->setSurface(surface);
+                    ALOGI_IF(err, "codec setSurface returned: %d", err);
+                    if (err == OK) {
+                        // reconnect to the old surface as MPS::Client will expect to
+                        // be able to disconnect from it.
+                        (void)native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
+                        mSurface = surface;
+                    }
+                }
+                if (err != OK) {
+                    // reconnect to the new surface on error as MPS::Client will expect to
+                    // be able to disconnect from it.
+                    (void)native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
+                }
+            }
+
+            sp<AMessage> response = new AMessage;
+            response->setInt32("err", err);
+            response->postReply(replyID);
+            break;
+        }
+
         default:
             DecoderBase::onMessageReceived(msg);
             break;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index ceccb7a..ed0be62 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -32,6 +32,9 @@
 
     virtual sp<AMessage> getStats() const;
 
+    // sets the output surface of video decoders.
+    virtual status_t setVideoSurface(const sp<Surface> &surface);
+
 protected:
     virtual ~Decoder();
 
@@ -50,6 +53,7 @@
     enum {
         kWhatCodecNotify         = 'cdcN',
         kWhatRenderBuffer        = 'rndr',
+        kWhatSetVideoSurface     = 'sSur'
     };
 
     sp<Surface> mSurface;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
index 8f030f0..b0dc01d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
@@ -27,6 +27,7 @@
 struct ABuffer;
 struct MediaCodec;
 class MediaBuffer;
+class Surface;
 
 struct NuPlayer::DecoderBase : public AHandler {
     DecoderBase(const sp<AMessage> &notify);
@@ -36,6 +37,7 @@
     void setParameters(const sp<AMessage> &params);
 
     void setRenderer(const sp<Renderer> &renderer);
+    virtual status_t setVideoSurface(const sp<Surface> &) { return INVALID_OPERATION; }
 
     status_t getInputBuffers(Vector<sp<ABuffer> > *dstBuffers) const;
     void signalFlush();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 7e55aac..13a7d94 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -266,6 +266,7 @@
         Mutex::Autolock autoLock(mLock);
         if (audio) {
             mNotifyCompleteAudio |= notifyComplete;
+            clearAudioFirstAnchorTime_l();
             ++mAudioQueueGeneration;
             ++mAudioDrainGeneration;
         } else {
@@ -275,7 +276,6 @@
         }
 
         clearAnchorTime_l();
-        clearAudioFirstAnchorTime_l();
         mVideoLateByUs = 0;
         mSyncQueues = false;
     }
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 9206b5c..cebd577 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -493,6 +493,7 @@
 ACodec::ACodec()
     : mQuirks(0),
       mNode(0),
+      mNativeWindowUsageBits(0),
       mSentFormat(false),
       mIsVideo(false),
       mIsEncoder(false),
@@ -642,7 +643,7 @@
         return OK;
     }
 
-    // allow keeping unset surface
+    // cannot switch from bytebuffers to surface
     if (mNativeWindow == NULL) {
         ALOGW("component was not configured with a surface");
         return INVALID_OPERATION;
@@ -661,11 +662,20 @@
         return INVALID_OPERATION;
     }
 
-    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow);
+    int usageBits = 0;
+    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow, &usageBits);
     if (err != OK) {
         return err;
     }
 
+    int ignoredFlags = (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER
+            | GRALLOC_USAGE_EXTERNAL_DISP);
+    // New output surface is not allowed to add new usage flag except ignored ones.
+    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
+        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
+        return BAD_VALUE;
+    }
+
     // get min undequeued count. We cannot switch to a surface that has a higher
     // undequeued count than we allocated.
     int minUndequeuedBuffers = 0;
@@ -747,6 +757,7 @@
     }
 
     mNativeWindow = nativeWindow;
+    mNativeWindowUsageBits = usageBits;
     return OK;
 }
 
@@ -868,7 +879,8 @@
     return OK;
 }
 
-status_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */) {
+status_t ACodec::setupNativeWindowSizeFormatAndUsage(
+        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */) {
     OMX_PARAM_PORTDEFINITIONTYPE def;
     InitOMXParams(&def);
     def.nPortIndex = kPortIndexOutput;
@@ -894,6 +906,7 @@
     }
 
     usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
+    *finalUsage = usage;
 
     ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
     return setNativeWindowSizeFormatAndUsage(
@@ -916,9 +929,10 @@
             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err == OK) {
-        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get());
+        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get(), &mNativeWindowUsageBits);
     }
     if (err != OK) {
+        mNativeWindowUsageBits = 0;
         return err;
     }
 
@@ -1937,6 +1951,7 @@
                     // to SW renderer
                     ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
                     mNativeWindow.clear();
+                    mNativeWindowUsageBits = 0;
                     haveNativeWindow = false;
                     usingSwRenderer = true;
                     if (storingMetadataInDecodedBuffers()) {
@@ -4542,9 +4557,7 @@
             sp<RefBase> obj;
             CHECK(msg->findObject("surface", &obj));
 
-            status_t err =
-                ADebug::isExperimentEnabled("legacy-setsurface") ? BAD_VALUE :
-                        mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
+            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
 
             sp<AMessage> response = new AMessage;
             response->setInt32("err", err);
@@ -5341,6 +5354,7 @@
     }
 
     mCodec->mNativeWindow.clear();
+    mCodec->mNativeWindowUsageBits = 0;
     mCodec->mNode = 0;
     mCodec->mOMX.clear();
     mCodec->mQuirks = 0;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index b696746..26b07d4 100755
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -4034,6 +4034,10 @@
             CHECK(mBuffer == NULL);
             return err;
         }
+        if (size > mBuffer->size()) {
+            ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
+            return ERROR_BUFFER_TOO_SMALL;
+        }
     }
 
     if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) {
@@ -4294,6 +4298,10 @@
             ALOGV("acquire_buffer returned %d", err);
             return err;
         }
+        if (size > mBuffer->size()) {
+            ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
+            return ERROR_BUFFER_TOO_SMALL;
+        }
     }
 
     const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 69f44ed..fb32d3a 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2528,6 +2528,7 @@
         err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
         if (err == BAD_VALUE) {
             ALOGI("native window already connected. Assuming no change of surface");
+            return err;
         } else if (err == OK) {
             // Require a fresh set of buffers after each connect by using a unique generation
             // number. Rely on the fact that max supported process id by Linux is 2^22.
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 7ea5cbd..5edc04c 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -216,6 +216,12 @@
                         String8(kPolicySupportsMultipleSecureCodecs),
                         String8(value.c_str())));
     }
+    if (mGlobalSettings->findString(kPolicySupportsSecureWithNonSecureCodec, &value)) {
+        policies.push_back(
+                MediaResourcePolicy(
+                        String8(kPolicySupportsSecureWithNonSecureCodec),
+                        String8(value.c_str())));
+    }
     if (policies.size() > 0) {
         sp<IServiceManager> sm = defaultServiceManager();
         sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index e2b6695..61147ff 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -204,6 +204,17 @@
     }
 }
 
+void ResourceManagerService::getClientForResource_l(
+        int callingPid, const MediaResource *res, Vector<sp<IResourceManagerClient>> *clients) {
+    if (res == NULL) {
+        return;
+    }
+    sp<IResourceManagerClient> client;
+    if (getLowestPriorityBiggestClient_l(callingPid, res->mType, &client)) {
+        clients->push_back(client);
+    }
+}
+
 bool ResourceManagerService::reclaimResource(
         int callingPid, const Vector<MediaResource> &resources) {
     String8 log = String8::format("reclaimResource(callingPid %d, resources %s)",
@@ -213,54 +224,61 @@
     Vector<sp<IResourceManagerClient>> clients;
     {
         Mutex::Autolock lock(mLock);
-        // first pass to handle secure/non-secure codec conflict
+        const MediaResource *secureCodec = NULL;
+        const MediaResource *nonSecureCodec = NULL;
+        const MediaResource *graphicMemory = NULL;
         for (size_t i = 0; i < resources.size(); ++i) {
             String8 type = resources[i].mType;
-            if (type == kResourceSecureCodec) {
-                if (!mSupportsMultipleSecureCodecs) {
-                    if (!getAllClients_l(callingPid, String8(kResourceSecureCodec), &clients)) {
-                        return false;
-                    }
-                }
-                if (!mSupportsSecureWithNonSecureCodec) {
-                    if (!getAllClients_l(callingPid, String8(kResourceNonSecureCodec), &clients)) {
-                        return false;
-                    }
-                }
+            if (resources[i].mType == kResourceSecureCodec) {
+                secureCodec = &resources[i];
             } else if (type == kResourceNonSecureCodec) {
-                if (!mSupportsSecureWithNonSecureCodec) {
-                    if (!getAllClients_l(callingPid, String8(kResourceSecureCodec), &clients)) {
-                        return false;
-                    }
+                nonSecureCodec = &resources[i];
+            } else if (type == kResourceGraphicMemory) {
+                graphicMemory = &resources[i];
+            }
+        }
+
+        // first pass to handle secure/non-secure codec conflict
+        if (secureCodec != NULL) {
+            if (!mSupportsMultipleSecureCodecs) {
+                if (!getAllClients_l(callingPid, String8(kResourceSecureCodec), &clients)) {
+                    return false;
+                }
+            }
+            if (!mSupportsSecureWithNonSecureCodec) {
+                if (!getAllClients_l(callingPid, String8(kResourceNonSecureCodec), &clients)) {
+                    return false;
+                }
+            }
+        }
+        if (nonSecureCodec != NULL) {
+            if (!mSupportsSecureWithNonSecureCodec) {
+                if (!getAllClients_l(callingPid, String8(kResourceSecureCodec), &clients)) {
+                    return false;
                 }
             }
         }
 
         if (clients.size() == 0) {
             // if no secure/non-secure codec conflict, run second pass to handle other resources.
-            for (size_t i = 0; i < resources.size(); ++i) {
-                String8 type = resources[i].mType;
-                if (type == kResourceGraphicMemory) {
-                    sp<IResourceManagerClient> client;
-                    if (!getLowestPriorityBiggestClient_l(callingPid, type, &client)) {
-                        return false;
-                    }
-                    clients.push_back(client);
-                }
-            }
+            getClientForResource_l(callingPid, graphicMemory, &clients);
         }
 
         if (clients.size() == 0) {
             // if we are here, run the third pass to free one codec with the same type.
-            for (size_t i = 0; i < resources.size(); ++i) {
-                String8 type = resources[i].mType;
-                if (type == kResourceSecureCodec || type == kResourceNonSecureCodec) {
-                    sp<IResourceManagerClient> client;
-                    if (!getLowestPriorityBiggestClient_l(callingPid, type, &client)) {
-                        return false;
-                    }
-                    clients.push_back(client);
-                }
+            getClientForResource_l(callingPid, secureCodec, &clients);
+            getClientForResource_l(callingPid, nonSecureCodec, &clients);
+        }
+
+        if (clients.size() == 0) {
+            // if we are here, run the fourth pass to free one codec with the different type.
+            if (secureCodec != NULL) {
+                MediaResource temp(String8(kResourceNonSecureCodec), 1);
+                getClientForResource_l(callingPid, &temp, &clients);
+            }
+            if (nonSecureCodec != NULL) {
+                MediaResource temp(String8(kResourceSecureCodec), 1);
+                getClientForResource_l(callingPid, &temp, &clients);
             }
         }
     }
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index 0d9d878..ca218fc 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -65,6 +65,9 @@
 
     virtual void removeResource(int64_t clientId);
 
+    // Tries to reclaim resource from processes with lower priority than the calling process
+    // according to the requested resources.
+    // Returns true if any resource has been reclaimed, otherwise returns false.
     virtual bool reclaimResource(int callingPid, const Vector<MediaResource> &resources);
 
 protected:
@@ -95,6 +98,11 @@
 
     bool isCallingPriorityHigher_l(int callingPid, int pid);
 
+    // A helper function basically calls getLowestPriorityBiggestClient_l and add the result client
+    // to the given Vector.
+    void getClientForResource_l(
+        int callingPid, const MediaResource *res, Vector<sp<IResourceManagerClient>> *clients);
+
     mutable Mutex mLock;
     sp<ProcessInfoInterface> mProcessInfo;
     sp<ServiceLog> mServiceLog;
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 3d53f1f..8ae6a55 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -79,6 +79,10 @@
 static const int kTestPid1 = 30;
 static const int kTestPid2 = 20;
 
+static const int kLowPriorityPid = 40;
+static const int kMidPriorityPid = 25;
+static const int kHighPriorityPid = 10;
+
 class ResourceManagerServiceTest : public ::testing::Test {
 public:
     ResourceManagerServiceTest()
@@ -227,15 +231,12 @@
         String8 type = String8(kResourceSecureCodec);
         String8 unknowType = String8("unknowType");
         Vector<sp<IResourceManagerClient> > clients;
-        int lowPriorityPid = 100;
-        EXPECT_FALSE(mService->getAllClients_l(lowPriorityPid, type, &clients));
-        int midPriorityPid = 25;
+        EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, &clients));
         // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
         // will fail.
-        EXPECT_FALSE(mService->getAllClients_l(midPriorityPid, type, &clients));
-        int highPriorityPid = 10;
-        EXPECT_TRUE(mService->getAllClients_l(highPriorityPid, unknowType, &clients));
-        EXPECT_TRUE(mService->getAllClients_l(highPriorityPid, type, &clients));
+        EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, &clients));
+        EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, unknowType, &clients));
+        EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, &clients));
 
         EXPECT_EQ(2u, clients.size());
         EXPECT_EQ(mTestClient3, clients[0]);
@@ -254,19 +255,19 @@
             mService->mSupportsSecureWithNonSecureCodec = true;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(40, resources));
-            EXPECT_FALSE(mService->reclaimResource(25, resources));
+            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
+            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
 
             // reclaim all secure codecs
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(true, false, true);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
 
             // call again should reclaim one largest graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(false, true, false);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(10, resources));
+            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
         }
 
         // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
@@ -276,15 +277,15 @@
             mService->mSupportsSecureWithNonSecureCodec = false;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(40, resources));
-            EXPECT_FALSE(mService->reclaimResource(25, resources));
+            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
+            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
 
             // reclaim all secure and non-secure codecs
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(true, true, true);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(true /* c1 */, true /* c2 */, true /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(10, resources));
+            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
         }
 
 
@@ -295,23 +296,23 @@
             mService->mSupportsSecureWithNonSecureCodec = false;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(40, resources));
-            EXPECT_FALSE(mService->reclaimResource(25, resources));
+            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
+            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
 
             // reclaim all non-secure codecs
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(false, true, false);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
             // call again should reclaim one largest graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(true, false, false);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
 
             // call again should reclaim another largest graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(false, false, true);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(10, resources));
+            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
         }
 
         // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
@@ -321,22 +322,22 @@
             mService->mSupportsSecureWithNonSecureCodec = true;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(40, resources));
+            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
 
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
             // one largest graphic memory from lowest process got reclaimed
-            verifyClients(true, false, false);
+            verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
 
             // call again should reclaim another graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(false, true, false);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
             // call again should reclaim another graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(false, false, true);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(10, resources));
+            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
         }
 
         // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
@@ -348,19 +349,17 @@
             Vector<MediaResource> resources;
             resources.push_back(MediaResource(String8(kResourceSecureCodec), 1));
 
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
             // secure codec from lowest process got reclaimed
-            verifyClients(true, false, false);
+            verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
 
             // call again should reclaim another secure codec from lowest process
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(false, false, true);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
 
-            // nothing left
-            EXPECT_FALSE(mService->reclaimResource(10, resources));
-
-            // clean up client 2 which still has non secure codec left
-            mService->removeResource((int64_t) mTestClient2.get());
+            // no more secure codec, non-secure codec will be reclaimed.
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
         }
     }
 
@@ -375,19 +374,19 @@
             mService->mSupportsSecureWithNonSecureCodec = false;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(40, resources));
-            EXPECT_FALSE(mService->reclaimResource(25, resources));
+            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
+            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
 
             // reclaim all secure codecs
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(true, false, true);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
 
             // call again should reclaim one graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(false, true, false);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(10, resources));
+            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
         }
 
 
@@ -397,22 +396,22 @@
             mService->mSupportsSecureWithNonSecureCodec = true;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(40, resources));
+            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
 
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
             // one largest graphic memory from lowest process got reclaimed
-            verifyClients(true, false, false);
+            verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
 
             // call again should reclaim another graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(false, true, false);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
             // call again should reclaim another graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
-            verifyClients(false, false, true);
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(10, resources));
+            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
         }
 
         // ### secure codec can coexist with non-secure codec ###
@@ -423,15 +422,15 @@
             Vector<MediaResource> resources;
             resources.push_back(MediaResource(String8(kResourceNonSecureCodec), 1));
 
-            EXPECT_TRUE(mService->reclaimResource(10, resources));
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
             // one non secure codec from lowest process got reclaimed
-            verifyClients(false, true, false);
+            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
-            // nothing left
-            EXPECT_FALSE(mService->reclaimResource(10, resources));
+            // no more non-secure codec, secure codec from lowest priority process will be reclaimed
+            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
 
-            // clean up client 1 and 3 which still have secure codec left
-            mService->removeResource((int64_t) mTestClient1.get());
+            // clean up client 3 which still left
             mService->removeResource((int64_t) mTestClient3.get());
         }
     }
@@ -439,12 +438,12 @@
     void testGetLowestPriorityBiggestClient() {
         String8 type = String8(kResourceGraphicMemory);
         sp<IResourceManagerClient> client;
-        EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(10, type, &client));
+        EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
 
         addResource();
 
-        EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(100, type, &client));
-        EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(10, type, &client));
+        EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, &client));
+        EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
 
         // kTestPid1 is the lowest priority process with kResourceGraphicMemory.
         // mTestClient1 has the largest kResourceGraphicMemory within kTestPid1.