Merge "Log Monitor condition updates to TableLogBuffer." into udc-dev
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() {
|
protected final String getTag() {
|
||||||
|
if (isOverridingCondition()) {
|
||||||
|
return mTag + "[OVRD]";
|
||||||
|
}
|
||||||
|
|
||||||
return mTag;
|
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
|
* Creates a new condition which will only be true when both this condition and all the provided
|
||||||
* conditions are true.
|
* conditions are true.
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.util.Log;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
|
import com.android.systemui.plugins.log.TableLogBufferBase;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -41,6 +42,7 @@ public class Monitor {
|
|||||||
private final String mTag = getClass().getSimpleName();
|
private final String mTag = getClass().getSimpleName();
|
||||||
private final Executor mExecutor;
|
private final Executor mExecutor;
|
||||||
private final Set<Condition> mPreconditions;
|
private final Set<Condition> mPreconditions;
|
||||||
|
private final TableLogBufferBase mLogBuffer;
|
||||||
|
|
||||||
private final HashMap<Condition, ArraySet<Subscription.Token>> mConditions = new HashMap<>();
|
private final HashMap<Condition, ArraySet<Subscription.Token>> mConditions = new HashMap<>();
|
||||||
private final HashMap<Subscription.Token, SubscriptionState> mSubscriptions = new HashMap<>();
|
private final HashMap<Subscription.Token, SubscriptionState> mSubscriptions = new HashMap<>();
|
||||||
@@ -160,11 +162,23 @@ public class Monitor {
|
|||||||
* Main constructor, allowing specifying preconditions.
|
* Main constructor, allowing specifying preconditions.
|
||||||
*/
|
*/
|
||||||
public Monitor(Executor executor, Set<Condition> 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;
|
mExecutor = executor;
|
||||||
mPreconditions = preconditions;
|
mPreconditions = preconditions;
|
||||||
|
mLogBuffer = logBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateConditionMetState(Condition condition) {
|
private void updateConditionMetState(Condition condition) {
|
||||||
|
if (mLogBuffer != null) {
|
||||||
|
mLogBuffer.logChange(/* prefix= */ "", condition.getTag(), condition.getState());
|
||||||
|
}
|
||||||
|
|
||||||
final ArraySet<Subscription.Token> subscriptions = mConditions.get(condition);
|
final ArraySet<Subscription.Token> subscriptions = mConditions.get(condition);
|
||||||
|
|
||||||
// It's possible the condition was removed between the time the callback occurred and
|
// It's possible the condition was removed between the time the callback occurred and
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ import com.android.systemui.flags.FlagsModule;
|
|||||||
import com.android.systemui.keyboard.KeyboardModule;
|
import com.android.systemui.keyboard.KeyboardModule;
|
||||||
import com.android.systemui.keyguard.data.BouncerViewModule;
|
import com.android.systemui.keyguard.data.BouncerViewModule;
|
||||||
import com.android.systemui.log.dagger.LogModule;
|
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.mediaprojection.appselector.MediaProjectionModule;
|
||||||
import com.android.systemui.model.SysUiState;
|
import com.android.systemui.model.SysUiState;
|
||||||
import com.android.systemui.motiontool.MotionToolModule;
|
import com.android.systemui.motiontool.MotionToolModule;
|
||||||
@@ -250,8 +252,8 @@ public abstract class SystemUIModule {
|
|||||||
@Provides
|
@Provides
|
||||||
@SystemUser
|
@SystemUser
|
||||||
static Monitor provideSystemUserMonitor(@Main Executor executor,
|
static Monitor provideSystemUserMonitor(@Main Executor executor,
|
||||||
SystemProcessCondition systemProcessCondition) {
|
SystemProcessCondition systemProcessCondition, @MonitorLog TableLogBuffer logBuffer) {
|
||||||
return new Monitor(executor, Collections.singleton(systemProcessCondition));
|
return new Monitor(executor, Collections.singleton(systemProcessCondition), logBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BindsOptionalOf
|
@BindsOptionalOf
|
||||||
|
|||||||
@@ -421,6 +421,14 @@ public class LogModule {
|
|||||||
return factory.create("BouncerLog", 250);
|
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.
|
* 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.dagger.qualifiers.Background
|
||||||
import com.android.systemui.log.LogLevel
|
import com.android.systemui.log.LogLevel
|
||||||
import com.android.systemui.log.LogcatEchoTracker
|
import com.android.systemui.log.LogcatEchoTracker
|
||||||
|
import com.android.systemui.plugins.log.TableLogBufferBase
|
||||||
import com.android.systemui.util.time.SystemClock
|
import com.android.systemui.util.time.SystemClock
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@@ -84,7 +85,7 @@ class TableLogBuffer(
|
|||||||
@Background private val bgDispatcher: CoroutineDispatcher,
|
@Background private val bgDispatcher: CoroutineDispatcher,
|
||||||
private val coroutineScope: CoroutineScope,
|
private val coroutineScope: CoroutineScope,
|
||||||
private val localLogcat: LogProxy = LogProxyDefault(),
|
private val localLogcat: LogProxy = LogProxyDefault(),
|
||||||
) : Dumpable {
|
) : Dumpable, TableLogBufferBase {
|
||||||
init {
|
init {
|
||||||
if (maxSize <= 0) {
|
if (maxSize <= 0) {
|
||||||
throw IllegalArgumentException("maxSize must be > 0")
|
throw IllegalArgumentException("maxSize must be > 0")
|
||||||
@@ -177,7 +178,7 @@ class TableLogBuffer(
|
|||||||
*
|
*
|
||||||
* @param isInitial see [TableLogBuffer.logChange(String, Boolean, (TableRowLogger) -> Unit].
|
* @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)
|
logChange(systemClock.currentTimeMillis(), prefix, columnName, value, isInitial)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +187,7 @@ class TableLogBuffer(
|
|||||||
*
|
*
|
||||||
* @param isInitial see [TableLogBuffer.logChange(String, Boolean, (TableRowLogger) -> Unit].
|
* @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)
|
logChange(systemClock.currentTimeMillis(), prefix, columnName, value, isInitial)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +196,7 @@ class TableLogBuffer(
|
|||||||
*
|
*
|
||||||
* @param isInitial see [TableLogBuffer.logChange(String, Boolean, (TableRowLogger) -> Unit].
|
* @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)
|
logChange(systemClock.currentTimeMillis(), prefix, columnName, value, isInitial)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.testing.AndroidTestingRunner;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
|
import com.android.systemui.plugins.log.TableLogBufferBase;
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||||
import com.android.systemui.util.time.FakeSystemClock;
|
import com.android.systemui.util.time.FakeSystemClock;
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ import org.mockito.Mockito;
|
|||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
import kotlinx.coroutines.CoroutineScope;
|
import kotlinx.coroutines.CoroutineScope;
|
||||||
@@ -59,6 +61,8 @@ public class ConditionMonitorTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private CoroutineScope mScope;
|
private CoroutineScope mScope;
|
||||||
|
@Mock
|
||||||
|
private TableLogBufferBase mLogBuffer;
|
||||||
|
|
||||||
private Monitor mConditionMonitor;
|
private Monitor mConditionMonitor;
|
||||||
|
|
||||||
@@ -630,4 +634,42 @@ public class ConditionMonitorTest extends SysuiTestCase {
|
|||||||
verify(callback).onActiveChanged(eq(true));
|
verify(callback).onActiveChanged(eq(true));
|
||||||
verify(callback).onConditionsChanged(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) {
|
public void fakeUpdateCondition(boolean isConditionMet) {
|
||||||
updateCondition(isConditionMet);
|
updateCondition(isConditionMet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void fakeClearCondition() {
|
||||||
|
clearCondition();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user