Merge "Log Monitor condition updates to TableLogBuffer." into udc-dev am: 6cca48d23d
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23061079 Change-Id: I1c8f1cbc52d3b1e04cdd630d1d5af46922030d32 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.plugins.log
|
||||
|
||||
/**
|
||||
* Base interface for a logger that logs changes in table format.
|
||||
*
|
||||
* This is a plugin interface for classes outside of SystemUI core.
|
||||
*/
|
||||
interface TableLogBufferBase {
|
||||
/**
|
||||
* Logs a String? change.
|
||||
*
|
||||
* For Java overloading.
|
||||
*/
|
||||
fun logChange(prefix: String, columnName: String, value: String?) {
|
||||
logChange(prefix, columnName, value, isInitial = false)
|
||||
}
|
||||
|
||||
/** Logs a String? change. */
|
||||
fun logChange(prefix: String, columnName: String, value: String?, isInitial: Boolean)
|
||||
|
||||
/**
|
||||
* Logs a Boolean change.
|
||||
*
|
||||
* For Java overloading.
|
||||
*/
|
||||
fun logChange(prefix: String, columnName: String, value: Boolean) {
|
||||
logChange(prefix, columnName, value, isInitial = false)
|
||||
}
|
||||
|
||||
/** Logs a Boolean change. */
|
||||
fun logChange(prefix: String, columnName: String, value: Boolean, isInitial: Boolean)
|
||||
|
||||
/**
|
||||
* Logs an Int? change.
|
||||
*
|
||||
* For Java overloading.
|
||||
*/
|
||||
fun logChange(prefix: String, columnName: String, value: Int?) {
|
||||
logChange(prefix, columnName, value, isInitial = false)
|
||||
}
|
||||
|
||||
/** Logs an Int? change. */
|
||||
fun logChange(prefix: String, columnName: String, value: Int?, isInitial: Boolean)
|
||||
}
|
||||
@@ -234,9 +234,26 @@ public abstract class Condition {
|
||||
}
|
||||
|
||||
protected final String getTag() {
|
||||
if (isOverridingCondition()) {
|
||||
return mTag + "[OVRD]";
|
||||
}
|
||||
|
||||
return mTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state of the condition.
|
||||
* - "Invalid", condition hasn't been set / not monitored
|
||||
* - "True", condition has been met
|
||||
* - "False", condition has not been met
|
||||
*/
|
||||
protected final String getState() {
|
||||
if (!isConditionSet()) {
|
||||
return "Invalid";
|
||||
}
|
||||
return isConditionMet() ? "True" : "False";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new condition which will only be true when both this condition and all the provided
|
||||
* conditions are true.
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.plugins.log.TableLogBufferBase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -41,6 +42,7 @@ public class Monitor {
|
||||
private final String mTag = getClass().getSimpleName();
|
||||
private final Executor mExecutor;
|
||||
private final Set<Condition> mPreconditions;
|
||||
private final TableLogBufferBase mLogBuffer;
|
||||
|
||||
private final HashMap<Condition, ArraySet<Subscription.Token>> mConditions = new HashMap<>();
|
||||
private final HashMap<Subscription.Token, SubscriptionState> mSubscriptions = new HashMap<>();
|
||||
@@ -160,11 +162,23 @@ public class Monitor {
|
||||
* Main constructor, allowing specifying preconditions.
|
||||
*/
|
||||
public Monitor(Executor executor, Set<Condition> preconditions) {
|
||||
this(executor, preconditions, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main constructor, allowing specifying preconditions and a log buffer for logging.
|
||||
*/
|
||||
public Monitor(Executor executor, Set<Condition> preconditions, TableLogBufferBase logBuffer) {
|
||||
mExecutor = executor;
|
||||
mPreconditions = preconditions;
|
||||
mLogBuffer = logBuffer;
|
||||
}
|
||||
|
||||
private void updateConditionMetState(Condition condition) {
|
||||
if (mLogBuffer != null) {
|
||||
mLogBuffer.logChange(/* prefix= */ "", condition.getTag(), condition.getState());
|
||||
}
|
||||
|
||||
final ArraySet<Subscription.Token> subscriptions = mConditions.get(condition);
|
||||
|
||||
// It's possible the condition was removed between the time the callback occurred and
|
||||
|
||||
@@ -56,6 +56,8 @@ import com.android.systemui.globalactions.ShutdownUiModule;
|
||||
import com.android.systemui.keyboard.KeyboardModule;
|
||||
import com.android.systemui.keyguard.data.BouncerViewModule;
|
||||
import com.android.systemui.log.dagger.LogModule;
|
||||
import com.android.systemui.log.dagger.MonitorLog;
|
||||
import com.android.systemui.log.table.TableLogBuffer;
|
||||
import com.android.systemui.mediaprojection.appselector.MediaProjectionModule;
|
||||
import com.android.systemui.model.SysUiState;
|
||||
import com.android.systemui.motiontool.MotionToolModule;
|
||||
@@ -252,8 +254,8 @@ public abstract class SystemUIModule {
|
||||
@Provides
|
||||
@SystemUser
|
||||
static Monitor provideSystemUserMonitor(@Main Executor executor,
|
||||
SystemProcessCondition systemProcessCondition) {
|
||||
return new Monitor(executor, Collections.singleton(systemProcessCondition));
|
||||
SystemProcessCondition systemProcessCondition, @MonitorLog TableLogBuffer logBuffer) {
|
||||
return new Monitor(executor, Collections.singleton(systemProcessCondition), logBuffer);
|
||||
}
|
||||
|
||||
@BindsOptionalOf
|
||||
|
||||
@@ -421,6 +421,14 @@ public class LogModule {
|
||||
return factory.create("BouncerLog", 250);
|
||||
}
|
||||
|
||||
/** Provides a table logging buffer for the Monitor. */
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@MonitorLog
|
||||
public static TableLogBuffer provideMonitorTableLogBuffer(TableLogBufferFactory factory) {
|
||||
return factory.create("MonitorLog", 250);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a {@link LogBuffer} for Udfps logs.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.log.dagger
|
||||
|
||||
import javax.inject.Qualifier
|
||||
import kotlin.annotation.Retention
|
||||
|
||||
/** Logger for Monitor. */
|
||||
@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class MonitorLog
|
||||
@@ -23,6 +23,7 @@ import com.android.systemui.common.buffer.RingBuffer
|
||||
import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.log.LogLevel
|
||||
import com.android.systemui.log.LogcatEchoTracker
|
||||
import com.android.systemui.plugins.log.TableLogBufferBase
|
||||
import com.android.systemui.util.time.SystemClock
|
||||
import java.io.PrintWriter
|
||||
import java.util.Locale
|
||||
@@ -84,7 +85,7 @@ class TableLogBuffer(
|
||||
@Background private val bgDispatcher: CoroutineDispatcher,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
private val localLogcat: LogProxy = LogProxyDefault(),
|
||||
) : Dumpable {
|
||||
) : Dumpable, TableLogBufferBase {
|
||||
init {
|
||||
if (maxSize <= 0) {
|
||||
throw IllegalArgumentException("maxSize must be > 0")
|
||||
@@ -177,7 +178,7 @@ class TableLogBuffer(
|
||||
*
|
||||
* @param isInitial see [TableLogBuffer.logChange(String, Boolean, (TableRowLogger) -> Unit].
|
||||
*/
|
||||
fun logChange(prefix: String, columnName: String, value: String?, isInitial: Boolean = false) {
|
||||
override fun logChange(prefix: String, columnName: String, value: String?, isInitial: Boolean) {
|
||||
logChange(systemClock.currentTimeMillis(), prefix, columnName, value, isInitial)
|
||||
}
|
||||
|
||||
@@ -186,7 +187,7 @@ class TableLogBuffer(
|
||||
*
|
||||
* @param isInitial see [TableLogBuffer.logChange(String, Boolean, (TableRowLogger) -> Unit].
|
||||
*/
|
||||
fun logChange(prefix: String, columnName: String, value: Boolean, isInitial: Boolean = false) {
|
||||
override fun logChange(prefix: String, columnName: String, value: Boolean, isInitial: Boolean) {
|
||||
logChange(systemClock.currentTimeMillis(), prefix, columnName, value, isInitial)
|
||||
}
|
||||
|
||||
@@ -195,7 +196,7 @@ class TableLogBuffer(
|
||||
*
|
||||
* @param isInitial see [TableLogBuffer.logChange(String, Boolean, (TableRowLogger) -> Unit].
|
||||
*/
|
||||
fun logChange(prefix: String, columnName: String, value: Int?, isInitial: Boolean = false) {
|
||||
override fun logChange(prefix: String, columnName: String, value: Int?, isInitial: Boolean) {
|
||||
logChange(systemClock.currentTimeMillis(), prefix, columnName, value, isInitial)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.testing.AndroidTestingRunner;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.log.TableLogBufferBase;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
@@ -44,6 +45,7 @@ import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope;
|
||||
@@ -59,6 +61,8 @@ public class ConditionMonitorTest extends SysuiTestCase {
|
||||
|
||||
@Mock
|
||||
private CoroutineScope mScope;
|
||||
@Mock
|
||||
private TableLogBufferBase mLogBuffer;
|
||||
|
||||
private Monitor mConditionMonitor;
|
||||
|
||||
@@ -630,4 +634,42 @@ public class ConditionMonitorTest extends SysuiTestCase {
|
||||
verify(callback).onActiveChanged(eq(true));
|
||||
verify(callback).onConditionsChanged(eq(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoggingCallback() {
|
||||
final Monitor monitor = new Monitor(mExecutor, Collections.emptySet(), mLogBuffer);
|
||||
|
||||
final FakeCondition condition = new FakeCondition(mScope);
|
||||
final FakeCondition overridingCondition = new FakeCondition(
|
||||
mScope,
|
||||
/* initialValue= */ false,
|
||||
/* overriding= */ true);
|
||||
|
||||
final Monitor.Callback callback = mock(Monitor.Callback.class);
|
||||
monitor.addSubscription(getDefaultBuilder(callback)
|
||||
.addCondition(condition)
|
||||
.addCondition(overridingCondition)
|
||||
.build());
|
||||
mExecutor.runAllReady();
|
||||
|
||||
// condition set to true
|
||||
condition.fakeUpdateCondition(true);
|
||||
mExecutor.runAllReady();
|
||||
verify(mLogBuffer).logChange("", "FakeCondition", "True");
|
||||
|
||||
// condition set to false
|
||||
condition.fakeUpdateCondition(false);
|
||||
mExecutor.runAllReady();
|
||||
verify(mLogBuffer).logChange("", "FakeCondition", "False");
|
||||
|
||||
// condition unset
|
||||
condition.fakeClearCondition();
|
||||
mExecutor.runAllReady();
|
||||
verify(mLogBuffer).logChange("", "FakeCondition", "Invalid");
|
||||
|
||||
// overriding condition set to true
|
||||
overridingCondition.fakeUpdateCondition(true);
|
||||
mExecutor.runAllReady();
|
||||
verify(mLogBuffer).logChange("", "FakeCondition[OVRD]", "True");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,4 +47,8 @@ public class FakeCondition extends Condition {
|
||||
public void fakeUpdateCondition(boolean isConditionMet) {
|
||||
updateCondition(isConditionMet);
|
||||
}
|
||||
|
||||
public void fakeClearCondition() {
|
||||
clearCondition();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user