1 /* <lambda>null2 * Copyright (C) 2024 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 package com.android.systemui.util.wakelock 18 19 import android.os.PowerManager 20 import android.util.Log 21 import com.android.systemui.util.wakelock.WakeLock.Builder.NO_TIMEOUT 22 import java.util.concurrent.ConcurrentHashMap 23 import java.util.concurrent.atomic.AtomicInteger 24 25 /** 26 * [PowerManager.WakeLock] wrapper that tracks acquire/release reasons and logs them if owning 27 * logger is enabled. 28 */ 29 class ClientTrackingWakeLock( 30 private val pmWakeLock: PowerManager.WakeLock, 31 private val logger: WakeLockLogger?, 32 private val maxTimeout: Long 33 ) : WakeLock { 34 35 private val activeClients = ConcurrentHashMap<String, AtomicInteger>() 36 37 override fun acquire(why: String) { 38 val count = activeClients.computeIfAbsent(why) { _ -> AtomicInteger(0) }.incrementAndGet() 39 logger?.logAcquire(pmWakeLock, why, count) 40 if (maxTimeout == NO_TIMEOUT) { 41 pmWakeLock.acquire() 42 } else { 43 pmWakeLock.acquire(maxTimeout) 44 } 45 } 46 47 override fun release(why: String) { 48 val count = activeClients[why]?.decrementAndGet() ?: -1 49 if (count < 0) { 50 Log.wtf(WakeLock.TAG, "Releasing WakeLock with invalid reason: $why") 51 // Restore count just in case. 52 activeClients[why]?.incrementAndGet() 53 return 54 } 55 56 logger?.logRelease(pmWakeLock, why, count) 57 pmWakeLock.release() 58 } 59 60 override fun wrap(r: Runnable): Runnable = WakeLock.wrapImpl(this, r) 61 62 fun activeClients(): Int = 63 activeClients.reduceValuesToInt(Long.MAX_VALUE, AtomicInteger::get, 0, Integer::sum) 64 65 override fun toString(): String { 66 return "active clients=${activeClients()}" 67 } 68 } 69