Loading services/mediaresourcemanager/ResourceManagerService.cpp +35 −7 Original line number Diff line number Diff line Loading @@ -200,16 +200,44 @@ status_t ResourceManagerService::dump(int fd, const Vector<String16>& /* args */ return OK; } struct SystemCallbackImpl : public ResourceManagerService::SystemCallbackInterface { SystemCallbackImpl() {} virtual void noteStartVideo(int uid) override { BatteryNotifier::getInstance().noteStartVideo(uid); } virtual void noteStopVideo(int uid) override { BatteryNotifier::getInstance().noteStopVideo(uid); } virtual void noteResetVideo() override { BatteryNotifier::getInstance().noteResetVideo(); } virtual bool requestCpusetBoost( bool enable, const sp<IInterface> &client) override { return android::requestCpusetBoost(enable, client); } protected: virtual ~SystemCallbackImpl() {} private: DISALLOW_EVIL_CONSTRUCTORS(SystemCallbackImpl); }; ResourceManagerService::ResourceManagerService() : ResourceManagerService(new ProcessInfo()) {} : ResourceManagerService(new ProcessInfo(), new SystemCallbackImpl()) {} ResourceManagerService::ResourceManagerService(sp<ProcessInfoInterface> processInfo) ResourceManagerService::ResourceManagerService( const sp<ProcessInfoInterface> &processInfo, const sp<SystemCallbackInterface> &systemResource) : mProcessInfo(processInfo), mSystemCB(systemResource), mServiceLog(new ServiceLog()), mSupportsMultipleSecureCodecs(true), mSupportsSecureWithNonSecureCodec(true), mCpuBoostCount(0) { BatteryNotifier::getInstance().noteResetVideo(); mSystemCB->noteResetVideo(); } ResourceManagerService::~ResourceManagerService() {} Loading Loading @@ -238,13 +266,13 @@ void ResourceManagerService::onFirstAdded( // Request it on every new instance of kCpuBoost, as the media.codec // could have died, if we only do it the first time subsequent instances // never gets the boost. if (requestCpusetBoost(true, this) != OK) { if (mSystemCB->requestCpusetBoost(true, this) != OK) { ALOGW("couldn't request cpuset boost"); } mCpuBoostCount++; } else if (resource.mType == MediaResource::kBattery && resource.mSubType == MediaResource::kVideoCodec) { BatteryNotifier::getInstance().noteStartVideo(clientInfo.uid); mSystemCB->noteStartVideo(clientInfo.uid); } } Loading @@ -254,11 +282,11 @@ void ResourceManagerService::onLastRemoved( && resource.mSubType == MediaResource::kUnspecifiedSubType && mCpuBoostCount > 0) { if (--mCpuBoostCount == 0) { requestCpusetBoost(false, this); mSystemCB->requestCpusetBoost(false, this); } } else if (resource.mType == MediaResource::kBattery && resource.mSubType == MediaResource::kVideoCodec) { BatteryNotifier::getInstance().noteStopVideo(clientInfo.uid); mSystemCB->noteStopVideo(clientInfo.uid); } } Loading services/mediaresourcemanager/ResourceManagerService.h +12 −1 Original line number Diff line number Diff line Loading @@ -51,12 +51,22 @@ class ResourceManagerService public BnResourceManagerService { public: struct SystemCallbackInterface : public RefBase { virtual void noteStartVideo(int uid) = 0; virtual void noteStopVideo(int uid) = 0; virtual void noteResetVideo() = 0; virtual bool requestCpusetBoost( bool enable, const sp<IInterface> &client) = 0; }; static char const *getServiceName() { return "media.resource_manager"; } virtual status_t dump(int fd, const Vector<String16>& args); ResourceManagerService(); explicit ResourceManagerService(sp<ProcessInfoInterface> processInfo); explicit ResourceManagerService( const sp<ProcessInfoInterface> &processInfo, const sp<SystemCallbackInterface> &systemResource); // IResourceManagerService interface virtual void config(const Vector<MediaResourcePolicy> &policies); Loading Loading @@ -118,6 +128,7 @@ private: mutable Mutex mLock; sp<ProcessInfoInterface> mProcessInfo; sp<SystemCallbackInterface> mSystemCB; sp<ServiceLog> mServiceLog; PidResourceInfosMap mMap; bool mSupportsMultipleSecureCodecs; Loading services/mediaresourcemanager/test/ResourceManagerService_test.cpp +150 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,62 @@ private: DISALLOW_EVIL_CONSTRUCTORS(TestProcessInfo); }; struct TestSystemCallback : public ResourceManagerService::SystemCallbackInterface { TestSystemCallback() : mLastEvent({EventType::INVALID, 0}), mEventCount(0) {} enum EventType { INVALID = -1, VIDEO_ON = 0, VIDEO_OFF = 1, VIDEO_RESET = 2, CPUSET_ENABLE = 3, CPUSET_DISABLE = 4, }; struct EventEntry { EventType type; int arg; }; virtual void noteStartVideo(int uid) override { mLastEvent = {EventType::VIDEO_ON, uid}; mEventCount++; } virtual void noteStopVideo(int uid) override { mLastEvent = {EventType::VIDEO_OFF, uid}; mEventCount++; } virtual void noteResetVideo() override { mLastEvent = {EventType::VIDEO_RESET, 0}; mEventCount++; } virtual bool requestCpusetBoost( bool enable, const sp<IInterface> &/*client*/) override { mLastEvent = {enable ? EventType::CPUSET_ENABLE : EventType::CPUSET_DISABLE, 0}; mEventCount++; return true; } size_t eventCount() { return mEventCount; } EventType lastEventType() { return mLastEvent.type; } EventEntry lastEvent() { return mLastEvent; } protected: virtual ~TestSystemCallback() {} private: EventEntry mLastEvent; size_t mEventCount; DISALLOW_EVIL_CONSTRUCTORS(TestSystemCallback); }; struct TestClient : public BnResourceManagerClient { TestClient(int pid, sp<ResourceManagerService> service) : mReclaimed(false), mPid(pid), mService(service) {} Loading Loading @@ -95,10 +151,17 @@ static const int kLowPriorityPid = 40; static const int kMidPriorityPid = 25; static const int kHighPriorityPid = 10; using EventType = TestSystemCallback::EventType; using EventEntry = TestSystemCallback::EventEntry; bool operator== (const EventEntry& lhs, const EventEntry& rhs) { return lhs.type == rhs.type && lhs.arg == rhs.arg; } class ResourceManagerServiceTest : public ::testing::Test { public: ResourceManagerServiceTest() : mService(new ResourceManagerService(new TestProcessInfo)), : mSystemCB(new TestSystemCallback()), mService(new ResourceManagerService(new TestProcessInfo, mSystemCB)), mTestClient1(new TestClient(kTestPid1, mService)), mTestClient2(new TestClient(kTestPid2, mService)), mTestClient3(new TestClient(kTestPid2, mService)) { Loading Loading @@ -578,6 +641,84 @@ protected: EXPECT_TRUE(mService->isCallingPriorityHigher_l(99, 100)); } void testBatteryStats() { // reset should always be called when ResourceManagerService is created (restarted) EXPECT_EQ(1u, mSystemCB->eventCount()); EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType()); // new client request should cause VIDEO_ON Vector<MediaResource> resources1; resources1.push_back(MediaResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1)); mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); EXPECT_EQ(2u, mSystemCB->eventCount()); EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid1}), mSystemCB->lastEvent()); // each client should only cause 1 VIDEO_ON mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); EXPECT_EQ(2u, mSystemCB->eventCount()); // new client request should cause VIDEO_ON Vector<MediaResource> resources2; resources2.push_back(MediaResource(MediaResource::kBattery, MediaResource::kVideoCodec, 2)); mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2); EXPECT_EQ(3u, mSystemCB->eventCount()); EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid2}), mSystemCB->lastEvent()); // partially remove mTestClient1's request, shouldn't be any VIDEO_OFF mService->removeResource(kTestPid1, getId(mTestClient1), resources1); EXPECT_EQ(3u, mSystemCB->eventCount()); // remove mTestClient1's request, should be VIDEO_OFF for kTestUid1 // (use resource2 to test removing more instances than previously requested) mService->removeResource(kTestPid1, getId(mTestClient1), resources2); EXPECT_EQ(4u, mSystemCB->eventCount()); EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid1}), mSystemCB->lastEvent()); // remove mTestClient2, should be VIDEO_OFF for kTestUid2 mService->removeClient(kTestPid2, getId(mTestClient2)); EXPECT_EQ(5u, mSystemCB->eventCount()); EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid2}), mSystemCB->lastEvent()); } void testCpusetBoost() { // reset should always be called when ResourceManagerService is created (restarted) EXPECT_EQ(1u, mSystemCB->eventCount()); EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType()); // new client request should cause CPUSET_ENABLE Vector<MediaResource> resources1; resources1.push_back(MediaResource(MediaResource::kCpuBoost, 1)); mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); EXPECT_EQ(2u, mSystemCB->eventCount()); EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType()); // each client should only cause 1 CPUSET_ENABLE mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); EXPECT_EQ(2u, mSystemCB->eventCount()); // new client request should cause CPUSET_ENABLE Vector<MediaResource> resources2; resources2.push_back(MediaResource(MediaResource::kCpuBoost, 2)); mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2); EXPECT_EQ(3u, mSystemCB->eventCount()); EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType()); // remove mTestClient2 should not cause CPUSET_DISABLE, mTestClient1 still active mService->removeClient(kTestPid2, getId(mTestClient2)); EXPECT_EQ(3u, mSystemCB->eventCount()); // remove 1 cpuboost from mTestClient1, should not be CPUSET_DISABLE (still 1 left) mService->removeResource(kTestPid1, getId(mTestClient1), resources1); EXPECT_EQ(3u, mSystemCB->eventCount()); // remove 2 cpuboost from mTestClient1, should be CPUSET_DISABLE // (use resource2 to test removing more than previously requested) mService->removeResource(kTestPid1, getId(mTestClient1), resources2); EXPECT_EQ(4u, mSystemCB->eventCount()); EXPECT_EQ(EventType::CPUSET_DISABLE, mSystemCB->lastEventType()); } sp<TestSystemCallback> mSystemCB; sp<ResourceManagerService> mService; sp<IResourceManagerClient> mTestClient1; sp<IResourceManagerClient> mTestClient2; Loading Loading @@ -629,4 +770,12 @@ TEST_F(ResourceManagerServiceTest, isCallingPriorityHigher_l) { testIsCallingPriorityHigher(); } TEST_F(ResourceManagerServiceTest, testBatteryStats) { testBatteryStats(); } TEST_F(ResourceManagerServiceTest, testCpusetBoost) { testCpusetBoost(); } } // namespace android Loading
services/mediaresourcemanager/ResourceManagerService.cpp +35 −7 Original line number Diff line number Diff line Loading @@ -200,16 +200,44 @@ status_t ResourceManagerService::dump(int fd, const Vector<String16>& /* args */ return OK; } struct SystemCallbackImpl : public ResourceManagerService::SystemCallbackInterface { SystemCallbackImpl() {} virtual void noteStartVideo(int uid) override { BatteryNotifier::getInstance().noteStartVideo(uid); } virtual void noteStopVideo(int uid) override { BatteryNotifier::getInstance().noteStopVideo(uid); } virtual void noteResetVideo() override { BatteryNotifier::getInstance().noteResetVideo(); } virtual bool requestCpusetBoost( bool enable, const sp<IInterface> &client) override { return android::requestCpusetBoost(enable, client); } protected: virtual ~SystemCallbackImpl() {} private: DISALLOW_EVIL_CONSTRUCTORS(SystemCallbackImpl); }; ResourceManagerService::ResourceManagerService() : ResourceManagerService(new ProcessInfo()) {} : ResourceManagerService(new ProcessInfo(), new SystemCallbackImpl()) {} ResourceManagerService::ResourceManagerService(sp<ProcessInfoInterface> processInfo) ResourceManagerService::ResourceManagerService( const sp<ProcessInfoInterface> &processInfo, const sp<SystemCallbackInterface> &systemResource) : mProcessInfo(processInfo), mSystemCB(systemResource), mServiceLog(new ServiceLog()), mSupportsMultipleSecureCodecs(true), mSupportsSecureWithNonSecureCodec(true), mCpuBoostCount(0) { BatteryNotifier::getInstance().noteResetVideo(); mSystemCB->noteResetVideo(); } ResourceManagerService::~ResourceManagerService() {} Loading Loading @@ -238,13 +266,13 @@ void ResourceManagerService::onFirstAdded( // Request it on every new instance of kCpuBoost, as the media.codec // could have died, if we only do it the first time subsequent instances // never gets the boost. if (requestCpusetBoost(true, this) != OK) { if (mSystemCB->requestCpusetBoost(true, this) != OK) { ALOGW("couldn't request cpuset boost"); } mCpuBoostCount++; } else if (resource.mType == MediaResource::kBattery && resource.mSubType == MediaResource::kVideoCodec) { BatteryNotifier::getInstance().noteStartVideo(clientInfo.uid); mSystemCB->noteStartVideo(clientInfo.uid); } } Loading @@ -254,11 +282,11 @@ void ResourceManagerService::onLastRemoved( && resource.mSubType == MediaResource::kUnspecifiedSubType && mCpuBoostCount > 0) { if (--mCpuBoostCount == 0) { requestCpusetBoost(false, this); mSystemCB->requestCpusetBoost(false, this); } } else if (resource.mType == MediaResource::kBattery && resource.mSubType == MediaResource::kVideoCodec) { BatteryNotifier::getInstance().noteStopVideo(clientInfo.uid); mSystemCB->noteStopVideo(clientInfo.uid); } } Loading
services/mediaresourcemanager/ResourceManagerService.h +12 −1 Original line number Diff line number Diff line Loading @@ -51,12 +51,22 @@ class ResourceManagerService public BnResourceManagerService { public: struct SystemCallbackInterface : public RefBase { virtual void noteStartVideo(int uid) = 0; virtual void noteStopVideo(int uid) = 0; virtual void noteResetVideo() = 0; virtual bool requestCpusetBoost( bool enable, const sp<IInterface> &client) = 0; }; static char const *getServiceName() { return "media.resource_manager"; } virtual status_t dump(int fd, const Vector<String16>& args); ResourceManagerService(); explicit ResourceManagerService(sp<ProcessInfoInterface> processInfo); explicit ResourceManagerService( const sp<ProcessInfoInterface> &processInfo, const sp<SystemCallbackInterface> &systemResource); // IResourceManagerService interface virtual void config(const Vector<MediaResourcePolicy> &policies); Loading Loading @@ -118,6 +128,7 @@ private: mutable Mutex mLock; sp<ProcessInfoInterface> mProcessInfo; sp<SystemCallbackInterface> mSystemCB; sp<ServiceLog> mServiceLog; PidResourceInfosMap mMap; bool mSupportsMultipleSecureCodecs; Loading
services/mediaresourcemanager/test/ResourceManagerService_test.cpp +150 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,62 @@ private: DISALLOW_EVIL_CONSTRUCTORS(TestProcessInfo); }; struct TestSystemCallback : public ResourceManagerService::SystemCallbackInterface { TestSystemCallback() : mLastEvent({EventType::INVALID, 0}), mEventCount(0) {} enum EventType { INVALID = -1, VIDEO_ON = 0, VIDEO_OFF = 1, VIDEO_RESET = 2, CPUSET_ENABLE = 3, CPUSET_DISABLE = 4, }; struct EventEntry { EventType type; int arg; }; virtual void noteStartVideo(int uid) override { mLastEvent = {EventType::VIDEO_ON, uid}; mEventCount++; } virtual void noteStopVideo(int uid) override { mLastEvent = {EventType::VIDEO_OFF, uid}; mEventCount++; } virtual void noteResetVideo() override { mLastEvent = {EventType::VIDEO_RESET, 0}; mEventCount++; } virtual bool requestCpusetBoost( bool enable, const sp<IInterface> &/*client*/) override { mLastEvent = {enable ? EventType::CPUSET_ENABLE : EventType::CPUSET_DISABLE, 0}; mEventCount++; return true; } size_t eventCount() { return mEventCount; } EventType lastEventType() { return mLastEvent.type; } EventEntry lastEvent() { return mLastEvent; } protected: virtual ~TestSystemCallback() {} private: EventEntry mLastEvent; size_t mEventCount; DISALLOW_EVIL_CONSTRUCTORS(TestSystemCallback); }; struct TestClient : public BnResourceManagerClient { TestClient(int pid, sp<ResourceManagerService> service) : mReclaimed(false), mPid(pid), mService(service) {} Loading Loading @@ -95,10 +151,17 @@ static const int kLowPriorityPid = 40; static const int kMidPriorityPid = 25; static const int kHighPriorityPid = 10; using EventType = TestSystemCallback::EventType; using EventEntry = TestSystemCallback::EventEntry; bool operator== (const EventEntry& lhs, const EventEntry& rhs) { return lhs.type == rhs.type && lhs.arg == rhs.arg; } class ResourceManagerServiceTest : public ::testing::Test { public: ResourceManagerServiceTest() : mService(new ResourceManagerService(new TestProcessInfo)), : mSystemCB(new TestSystemCallback()), mService(new ResourceManagerService(new TestProcessInfo, mSystemCB)), mTestClient1(new TestClient(kTestPid1, mService)), mTestClient2(new TestClient(kTestPid2, mService)), mTestClient3(new TestClient(kTestPid2, mService)) { Loading Loading @@ -578,6 +641,84 @@ protected: EXPECT_TRUE(mService->isCallingPriorityHigher_l(99, 100)); } void testBatteryStats() { // reset should always be called when ResourceManagerService is created (restarted) EXPECT_EQ(1u, mSystemCB->eventCount()); EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType()); // new client request should cause VIDEO_ON Vector<MediaResource> resources1; resources1.push_back(MediaResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1)); mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); EXPECT_EQ(2u, mSystemCB->eventCount()); EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid1}), mSystemCB->lastEvent()); // each client should only cause 1 VIDEO_ON mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); EXPECT_EQ(2u, mSystemCB->eventCount()); // new client request should cause VIDEO_ON Vector<MediaResource> resources2; resources2.push_back(MediaResource(MediaResource::kBattery, MediaResource::kVideoCodec, 2)); mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2); EXPECT_EQ(3u, mSystemCB->eventCount()); EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid2}), mSystemCB->lastEvent()); // partially remove mTestClient1's request, shouldn't be any VIDEO_OFF mService->removeResource(kTestPid1, getId(mTestClient1), resources1); EXPECT_EQ(3u, mSystemCB->eventCount()); // remove mTestClient1's request, should be VIDEO_OFF for kTestUid1 // (use resource2 to test removing more instances than previously requested) mService->removeResource(kTestPid1, getId(mTestClient1), resources2); EXPECT_EQ(4u, mSystemCB->eventCount()); EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid1}), mSystemCB->lastEvent()); // remove mTestClient2, should be VIDEO_OFF for kTestUid2 mService->removeClient(kTestPid2, getId(mTestClient2)); EXPECT_EQ(5u, mSystemCB->eventCount()); EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid2}), mSystemCB->lastEvent()); } void testCpusetBoost() { // reset should always be called when ResourceManagerService is created (restarted) EXPECT_EQ(1u, mSystemCB->eventCount()); EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType()); // new client request should cause CPUSET_ENABLE Vector<MediaResource> resources1; resources1.push_back(MediaResource(MediaResource::kCpuBoost, 1)); mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); EXPECT_EQ(2u, mSystemCB->eventCount()); EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType()); // each client should only cause 1 CPUSET_ENABLE mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); EXPECT_EQ(2u, mSystemCB->eventCount()); // new client request should cause CPUSET_ENABLE Vector<MediaResource> resources2; resources2.push_back(MediaResource(MediaResource::kCpuBoost, 2)); mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2); EXPECT_EQ(3u, mSystemCB->eventCount()); EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType()); // remove mTestClient2 should not cause CPUSET_DISABLE, mTestClient1 still active mService->removeClient(kTestPid2, getId(mTestClient2)); EXPECT_EQ(3u, mSystemCB->eventCount()); // remove 1 cpuboost from mTestClient1, should not be CPUSET_DISABLE (still 1 left) mService->removeResource(kTestPid1, getId(mTestClient1), resources1); EXPECT_EQ(3u, mSystemCB->eventCount()); // remove 2 cpuboost from mTestClient1, should be CPUSET_DISABLE // (use resource2 to test removing more than previously requested) mService->removeResource(kTestPid1, getId(mTestClient1), resources2); EXPECT_EQ(4u, mSystemCB->eventCount()); EXPECT_EQ(EventType::CPUSET_DISABLE, mSystemCB->lastEventType()); } sp<TestSystemCallback> mSystemCB; sp<ResourceManagerService> mService; sp<IResourceManagerClient> mTestClient1; sp<IResourceManagerClient> mTestClient2; Loading Loading @@ -629,4 +770,12 @@ TEST_F(ResourceManagerServiceTest, isCallingPriorityHigher_l) { testIsCallingPriorityHigher(); } TEST_F(ResourceManagerServiceTest, testBatteryStats) { testBatteryStats(); } TEST_F(ResourceManagerServiceTest, testCpusetBoost) { testCpusetBoost(); } } // namespace android