1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "chre/platform/slpi/see/island_vote_client.h" 18 19 #include <cinttypes> 20 21 #include "chre/platform/assert.h" 22 #include "chre/platform/fatal_error.h" 23 #include "chre/platform/log.h" 24 #include "chre/platform/system_time.h" 25 #include "chre/util/lock_guard.h" 26 27 namespace chre { 28 29 #ifdef CHRE_SLPI_UIMG_ENABLED 30 constexpr Seconds IslandVoteClient::kSeeMaxBigImageDuration; 31 #endif // CHRE_SLPI_UIMG_ENABLED 32 33 IslandVoteClient::IslandVoteClient(const char *clientName) { 34 #ifdef CHRE_SLPI_UIMG_ENABLED 35 mClientHandle = sns_island_aggregator_register_client(clientName); 36 if (mClientHandle == nullptr) { 37 FATAL_ERROR("Island aggregator client register failed"); 38 } 39 #endif // CHRE_SLPI_UIMG_ENABLED 40 } 41 42 IslandVoteClient::~IslandVoteClient() { 43 #ifdef CHRE_SLPI_UIMG_ENABLED 44 sns_island_aggregator_deregister_client(mClientHandle); 45 #endif // CHRE_SLPI_UIMG_ENABLED 46 } 47 48 bool IslandVoteClient::voteBigImage(bool bigImage) { 49 #ifdef CHRE_SLPI_UIMG_ENABLED 50 bool success = true; 51 52 { 53 LockGuard<Mutex> lock(mMutex); 54 mLastBigImageRequest = bigImage; 55 56 bool needBigImage = (bigImage || mBigImageRefCount > 0); 57 if (needBigImage != mLastBigImageVote) { 58 success = voteSnsPowerMode(needBigImage); 59 mLastBigImageVote = needBigImage; 60 } 61 } 62 return success; 63 #else 64 return true; 65 #endif // CHRE_SLPI_UIMG_ENABLED 66 } 67 68 #ifdef CHRE_SLPI_UIMG_ENABLED 69 void IslandVoteClient::incrementBigImageRefCount() { 70 LockGuard<Mutex> lock(mMutex); 71 72 if (mBigImageRefCount++ == 0) { 73 mRefCountStart = Milliseconds(SystemTime::getMonotonicTime()); 74 LOGW("Big image ref count begins"); 75 76 if (!mLastBigImageVote) { 77 // Do not call voteBigImage() directly as it will override 78 // mLastBigImageRequest. 79 voteSnsPowerMode(true /* bigImage */); 80 mLastBigImageVote = true; 81 } 82 } else { 83 checkBigImageDuration(); 84 } 85 } 86 87 void IslandVoteClient::decrementBigImageRefCount() { 88 LockGuard<Mutex> lock(mMutex); 89 CHRE_ASSERT_LOG(mBigImageRefCount > 0, 90 "Tried to decrement big image ref count when it's 0"); 91 92 uint64_t duration = checkBigImageDuration(); 93 if (--mBigImageRefCount == 0) { 94 LOGW("Big image ref count ends: %" PRIu64 " ms", duration); 95 96 // There's no big image activity now, restore the intended uimg power state. 97 if (!mLastBigImageRequest) { 98 voteSnsPowerMode(false /* bigImage */); 99 mLastBigImageVote = false; 100 } 101 } 102 } 103 104 bool IslandVoteClient::voteSnsPowerMode(bool bigImage) { 105 sns_rc rc = bigImage ? sns_island_block(mClientHandle) 106 : sns_island_unblock(mClientHandle); 107 108 // TODO: (b/74524281) define success = (rc == SNS_RC_SUCCESS). 109 bool success = (rc != SNS_RC_FAILED); 110 if (!success) { 111 LOGE("Failed to vote for bigImage %d with result %d", bigImage, rc); 112 } 113 return success; 114 } 115 116 uint64_t IslandVoteClient::checkBigImageDuration() const { 117 uint64_t duration = 0; 118 if (mBigImageRefCount > 0) { 119 duration = Milliseconds(SystemTime::getMonotonicTime()).getMilliseconds() - 120 mRefCountStart.getMilliseconds(); 121 } 122 123 // Bimg memory fallback only intends to handle a surge of uimg memory 124 // requests. If there's a prolonged period of memory fallback, this might 125 // indicate a memory leak or inadequate uimg heap size. 126 if (duration > kSeeMaxBigImageDuration.getMilliseconds()) { 127 FATAL_ERROR("Forced into big image for %" PRIu64 " msec", duration); 128 } 129 return duration; 130 } 131 #endif // CHRE_SLPI_UIMG_ENABLED 132 133 //! Explicitly instantiate the IslandVoteClient singleton to reduce code size. 134 template class Singleton<IslandVoteClient>; 135 136 } // namespace chre 137