summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Peter Kalauskas <peskal@google.com> 2023-04-12 12:41:58 -0700
committer Peter Kalauskas <peskal@google.com> 2023-04-13 11:48:50 -0700
commit7eda3bbc854d812068d56dfecd80d083a60cd8f2 (patch)
tree3c80db2be0df2a0a082d157bc7e4db4c09a22f4b
parentfcea4de7d7914890e3513e86ef8f3c822b25881c (diff)
New log buffer for debugging WakeLocks
Test: adb shell dumpsys activity service \ com.android.systemui/.dump.SystemUIAuxiliaryDumpService Bug: 258690929 Change-Id: I7fd1a109f60bda0a22b9e1ecc529fa78e5e20054
-rw-r--r--packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListener.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLockLog.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLockLogger.kt50
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/util/wakelock/WakeLockFake.java2
10 files changed, 158 insertions, 38 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt
index f9613d505d87..f47275f8f850 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt
@@ -24,16 +24,13 @@ class BroadcastSender @Inject constructor(
@Background private val bgExecutor: Executor
) {
- private val WAKE_LOCK_TAG = "SysUI:BroadcastSender"
- private val WAKE_LOCK_SEND_REASON = "sendInBackground"
-
/**
* Sends broadcast via [Context.sendBroadcast] on background thread to avoid blocking
* synchronous binder call.
*/
@AnyThread
fun sendBroadcast(intent: Intent) {
- sendInBackground {
+ sendInBackground("$intent") {
context.sendBroadcast(intent)
}
}
@@ -44,7 +41,7 @@ class BroadcastSender @Inject constructor(
*/
@AnyThread
fun sendBroadcast(intent: Intent, receiverPermission: String?) {
- sendInBackground {
+ sendInBackground("$intent") {
context.sendBroadcast(intent, receiverPermission)
}
}
@@ -55,7 +52,7 @@ class BroadcastSender @Inject constructor(
*/
@AnyThread
fun sendBroadcastAsUser(intent: Intent, userHandle: UserHandle) {
- sendInBackground {
+ sendInBackground("$intent") {
context.sendBroadcastAsUser(intent, userHandle)
}
}
@@ -66,7 +63,7 @@ class BroadcastSender @Inject constructor(
*/
@AnyThread
fun sendBroadcastAsUser(intent: Intent, userHandle: UserHandle, receiverPermission: String?) {
- sendInBackground {
+ sendInBackground("$intent") {
context.sendBroadcastAsUser(intent, userHandle, receiverPermission)
}
}
@@ -82,7 +79,7 @@ class BroadcastSender @Inject constructor(
receiverPermission: String?,
options: Bundle?
) {
- sendInBackground {
+ sendInBackground("$intent") {
context.sendBroadcastAsUser(intent, userHandle, receiverPermission, options)
}
}
@@ -98,7 +95,7 @@ class BroadcastSender @Inject constructor(
receiverPermission: String?,
appOp: Int
) {
- sendInBackground {
+ sendInBackground("$intent") {
context.sendBroadcastAsUser(intent, userHandle, receiverPermission, appOp)
}
}
@@ -108,7 +105,7 @@ class BroadcastSender @Inject constructor(
*/
@AnyThread
fun closeSystemDialogs() {
- sendInBackground {
+ sendInBackground("closeSystemDialogs") {
context.closeSystemDialogs()
}
}
@@ -116,17 +113,21 @@ class BroadcastSender @Inject constructor(
/**
* Dispatches parameter on background executor while holding a wakelock.
*/
- private fun sendInBackground(callable: () -> Unit) {
+ private fun sendInBackground(reason: String, callable: () -> Unit) {
val broadcastWakelock = wakeLockBuilder.setTag(WAKE_LOCK_TAG)
.setMaxTimeout(5000)
.build()
- broadcastWakelock.acquire(WAKE_LOCK_SEND_REASON)
+ broadcastWakelock.acquire(reason)
bgExecutor.execute {
try {
callable.invoke()
} finally {
- broadcastWakelock.release(WAKE_LOCK_SEND_REASON)
+ broadcastWakelock.release(reason)
}
}
}
+
+ companion object {
+ private const val WAKE_LOCK_TAG = "SysUI:BroadcastSender"
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index bafd2e70a676..573de9737eb8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -60,6 +60,7 @@ import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.util.wakelock.SettableWakeLock;
import com.android.systemui.util.wakelock.WakeLock;
+import com.android.systemui.util.wakelock.WakeLockLogger;
import java.util.Date;
import java.util.Locale;
@@ -148,6 +149,8 @@ public class KeyguardSliceProvider extends SliceProvider implements
private int mStatusBarState;
private boolean mMediaIsVisible;
private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;
+ @Inject
+ WakeLockLogger mWakeLockLogger;
/**
* Receiver responsible for time ticking and updating the date format.
@@ -305,8 +308,8 @@ public class KeyguardSliceProvider extends SliceProvider implements
@Override
public boolean onCreateSliceProvider() {
mContextAvailableCallback.onContextAvailable(getContext());
- mMediaWakeLock = new SettableWakeLock(WakeLock.createPartial(getContext(), "media"),
- "media");
+ mMediaWakeLock = new SettableWakeLock(
+ WakeLock.createPartial(getContext(), mWakeLockLogger, "media"), "media");
synchronized (KeyguardSliceProvider.sInstanceLock) {
KeyguardSliceProvider oldInstance = KeyguardSliceProvider.sInstance;
if (oldInstance != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 3775e2c6bbee..7edb37832c4f 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -31,6 +31,7 @@ import com.android.systemui.plugins.log.LogcatEchoTrackerDebug;
import com.android.systemui.plugins.log.LogcatEchoTrackerProd;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.util.Compile;
+import com.android.systemui.util.wakelock.WakeLockLog;
import dagger.Module;
import dagger.Provides;
@@ -168,6 +169,14 @@ public class LogModule {
false /* systrace */);
}
+ /** Provides a logging buffer for {@link com.android.systemui.broadcast.BroadcastSender} */
+ @Provides
+ @SysUISingleton
+ @WakeLockLog
+ public static LogBuffer provideWakeLockLog(LogBufferFactory factory) {
+ return factory.create("WakeLockLog", 500 /* maxSize */, false /* systrace */);
+ }
+
/** Provides a logging buffer for all logs related to Toasts shown by SystemUI. */
@Provides
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
index e4ebea9483c7..972895d4a192 100644
--- a/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
@@ -62,6 +62,7 @@ public class DelayedWakeLock implements WakeLock {
*/
public static class Builder {
private final Context mContext;
+ private final WakeLockLogger mLogger;
private String mTag;
private Handler mHandler;
@@ -69,8 +70,9 @@ public class DelayedWakeLock implements WakeLock {
* Constructor for DelayedWakeLock.Builder
*/
@Inject
- public Builder(Context context) {
+ public Builder(Context context, WakeLockLogger logger) {
mContext = context;
+ mLogger = logger;
}
/**
@@ -95,7 +97,7 @@ public class DelayedWakeLock implements WakeLock {
* Build the DelayedWakeLock.
*/
public DelayedWakeLock build() {
- return new DelayedWakeLock(mHandler, WakeLock.createPartial(mContext, mTag));
+ return new DelayedWakeLock(mHandler, WakeLock.createPartial(mContext, mLogger, mTag));
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListener.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListener.java
index 283be867ffd9..dcc943531565 100644
--- a/packages/SystemUI/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListener.java
@@ -33,7 +33,7 @@ public class KeepAwakeAnimationListener extends AnimatorListenerAdapter
public KeepAwakeAnimationListener(Context context) {
Assert.isMainThread();
if (sWakeLock == null) {
- sWakeLock = WakeLock.createPartial(context, "animation");
+ sWakeLock = WakeLock.createPartial(context, null, "animation");
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
index f320d071b54f..6128feee8116 100644
--- a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
@@ -29,8 +29,8 @@ import javax.inject.Inject;
/** WakeLock wrapper for testability */
public interface WakeLock {
- static final String TAG = "WakeLock";
- static final String REASON_WRAP = "wrap";
+ String TAG = "WakeLock";
+ String REASON_WRAP = "wrap";
/**
* Default wake-lock timeout in milliseconds, to avoid battery regressions.
@@ -57,22 +57,32 @@ public interface WakeLock {
/** @see android.os.PowerManager.WakeLock#wrap(Runnable) */
Runnable wrap(Runnable r);
- static WakeLock createPartial(Context context, String tag) {
- return createPartial(context, tag, DEFAULT_MAX_TIMEOUT);
+ /**
+ * Creates a {@link WakeLock} that has a default release timeout and flags.
+ * @see android.os.PowerManager.WakeLock#acquire(long)
+ */
+ static WakeLock createPartial(Context context, WakeLockLogger logger, String tag) {
+ return createPartial(context, logger, tag, DEFAULT_MAX_TIMEOUT);
}
/**
- * Creates a {@link WakeLock} that has a default release timeout.
- * @see android.os.PowerManager.WakeLock#acquire(long) */
- static WakeLock createPartial(Context context, String tag, long maxTimeout) {
- return wrap(createWakeLockInner(context, tag, DEFAULT_LEVELS_AND_FLAGS), maxTimeout);
+ * Creates a {@link WakeLock} that has default flags.
+ * @see android.os.PowerManager.WakeLock#acquire(long)
+ */
+ static WakeLock createPartial(
+ Context context, WakeLockLogger logger, String tag, long maxTimeout) {
+ return wrap(
+ createWakeLockInner(context, tag, DEFAULT_LEVELS_AND_FLAGS), logger, maxTimeout);
}
/**
- * Creates a {@link WakeLock} that has a default release timeout and flags.
+ * Creates a {@link WakeLock}.
+ * @see android.os.PowerManager.WakeLock#acquire(long)
*/
- static WakeLock createWakeLock(Context context, String tag, int flags, long maxTimeout) {
- return wrap(createWakeLockInner(context, tag, flags), maxTimeout);
+ static WakeLock createWakeLock(
+ Context context, WakeLockLogger logger, String tag, int flags, long maxTimeout) {
+ return wrap(
+ createWakeLockInner(context, tag, flags), logger, maxTimeout);
}
@VisibleForTesting
@@ -100,14 +110,19 @@ public interface WakeLock {
* @return The new wake lock.
*/
@VisibleForTesting
- static WakeLock wrap(final PowerManager.WakeLock inner, long maxTimeout) {
+ static WakeLock wrap(
+ final PowerManager.WakeLock inner, WakeLockLogger logger, long maxTimeout) {
return new WakeLock() {
private final HashMap<String, Integer> mActiveClients = new HashMap<>();
/** @see PowerManager.WakeLock#acquire() */
public void acquire(String why) {
mActiveClients.putIfAbsent(why, 0);
- mActiveClients.put(why, mActiveClients.get(why) + 1);
+ int count = mActiveClients.get(why) + 1;
+ mActiveClients.put(why, count);
+ if (logger != null) {
+ logger.logAcquire(inner, why, count);
+ }
inner.acquire(maxTimeout);
}
@@ -118,10 +133,15 @@ public interface WakeLock {
Log.wtf(TAG, "Releasing WakeLock with invalid reason: " + why,
new Throwable());
return;
- } else if (count == 1) {
+ }
+ count--;
+ if (count == 0) {
mActiveClients.remove(why);
} else {
- mActiveClients.put(why, count - 1);
+ mActiveClients.put(why, count);
+ }
+ if (logger != null) {
+ logger.logRelease(inner, why, count);
}
inner.release();
}
@@ -133,7 +153,7 @@ public interface WakeLock {
@Override
public String toString() {
- return "active clients= " + mActiveClients.toString();
+ return "active clients= " + mActiveClients;
}
};
}
@@ -143,13 +163,15 @@ public interface WakeLock {
*/
class Builder {
private final Context mContext;
+ private final WakeLockLogger mLogger;
private String mTag;
private int mLevelsAndFlags = DEFAULT_LEVELS_AND_FLAGS;
private long mMaxTimeout = DEFAULT_MAX_TIMEOUT;
@Inject
- public Builder(Context context) {
+ public Builder(Context context, WakeLockLogger logger) {
mContext = context;
+ mLogger = logger;
}
public Builder setTag(String tag) {
@@ -168,7 +190,7 @@ public interface WakeLock {
}
public WakeLock build() {
- return WakeLock.createWakeLock(mContext, mTag, mLevelsAndFlags, mMaxTimeout);
+ return WakeLock.createWakeLock(mContext, mLogger, mTag, mLevelsAndFlags, mMaxTimeout);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLockLog.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLockLog.java
new file mode 100644
index 000000000000..59cb0525a7e9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLockLog.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.wakelock;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.plugins.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/** A {@link LogBuffer} for BroadcastSender-related messages. */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface WakeLockLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLockLogger.kt b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLockLogger.kt
new file mode 100644
index 000000000000..951903dc29bd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLockLogger.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.wakelock
+
+import android.os.PowerManager
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+import javax.inject.Inject
+
+class WakeLockLogger @Inject constructor(@WakeLockLog private val buffer: LogBuffer) {
+ fun logAcquire(wakeLock: PowerManager.WakeLock, reason: String, count: Int) {
+ buffer.log(
+ WakeLock.TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = wakeLock.tag
+ str2 = reason
+ int1 = count
+ },
+ { "Acquire tag=$str1 reason=$str2 count=$int1" }
+ )
+ }
+
+ fun logRelease(wakeLock: PowerManager.WakeLock, reason: String, count: Int) {
+ buffer.log(
+ WakeLock.TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = wakeLock.tag
+ str2 = reason
+ int1 = count
+ },
+ { "Release tag=$str1 reason=$str2 count=$int1" }
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
index 6e109eafd748..23a9207ec643 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
@@ -45,7 +45,7 @@ public class WakeLockTest extends SysuiTestCase {
mInner = WakeLock.createWakeLockInner(mContext,
WakeLockTest.class.getName(),
PowerManager.PARTIAL_WAKE_LOCK);
- mWakeLock = WakeLock.wrap(mInner, 20000);
+ mWakeLock = WakeLock.wrap(mInner, null, 20000);
}
@After
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/wakelock/WakeLockFake.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/wakelock/WakeLockFake.java
index 553b8a42edc8..cd2ff0b13027 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/wakelock/WakeLockFake.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/wakelock/WakeLockFake.java
@@ -55,7 +55,7 @@ public class WakeLockFake implements WakeLock {
private WakeLock mWakeLock;
public Builder(Context context) {
- super(context);
+ super(context, null);
}
public void setWakeLock(WakeLock wakeLock) {