Loading packages/SystemUI/src/com/android/systemui/log/Event.java 0 → 100644 +67 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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; import android.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Stores information about an event that occurred in SystemUI to be used for debugging and triage. * Every event has a time stamp, log level and message. * Events are stored in {@link SysuiLog} and can be printed in a dumpsys. */ public class Event { public static final int UNINITIALIZED = -1; @IntDef({ERROR, WARN, INFO, DEBUG, VERBOSE}) @Retention(RetentionPolicy.SOURCE) public @interface Level {} public static final int VERBOSE = 2; public static final int DEBUG = 3; public static final int INFO = 4; public static final int WARN = 5; public static final int ERROR = 6; private long mTimestamp; private @Level int mLogLevel = DEBUG; protected String mMessage; public Event(String message) { mTimestamp = System.currentTimeMillis(); mMessage = message; } public Event(@Level int logLevel, String message) { mTimestamp = System.currentTimeMillis(); mLogLevel = logLevel; mMessage = message; } public String getMessage() { return mMessage; } public long getTimestamp() { return mTimestamp; } public @Level int getLogLevel() { return mLogLevel; } } packages/SystemUI/src/com/android/systemui/log/RichEvent.java 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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; /** * Stores information about an event that occurred in SystemUI to be used for debugging and triage. * Every rich event has a time stamp, event type, and log level, with the option to provide the * reason this event was triggered. * Events are stored in {@link SysuiLog} and can be printed in a dumpsys. */ public abstract class RichEvent extends Event { private final int mType; private final String mReason; /** * Create a rich event that includes an event type that matches with an index in the array * getEventLabels(). */ public RichEvent(@Event.Level int logLevel, int type, String reason) { super(logLevel, null); final int numEvents = getEventLabels().length; if (type < 0 || type >= numEvents) { throw new IllegalArgumentException("Unsupported event type. Events only supported" + " from 0 to " + (numEvents - 1) + ", but given type=" + type); } mType = type; mReason = reason; mMessage = getEventLabels()[mType] + " " + mReason; } /** * Returns an array of the event labels. The index represents the event type and the * corresponding String stored at that index is the user-readable representation of that event. * @return array of user readable events, where the index represents its event type constant */ public abstract String[] getEventLabels(); public int getType() { return mType; } public String getReason() { return mReason; } /** * Builder to build a RichEvent. * @param <B> Log specific builder that is extending this builder */ public abstract static class Builder<B extends Builder<B>> { public static final int UNINITIALIZED = -1; private B mBuilder = getBuilder(); protected int mType = UNINITIALIZED; protected String mReason; protected @Level int mLogLevel; /** * Get the log-specific builder. */ public abstract B getBuilder(); /** * Build the log-specific event. */ public abstract RichEvent build(); /** * Optional - set the log level. Defaults to DEBUG. */ public B setLogLevel(@Level int logLevel) { mLogLevel = logLevel; return mBuilder; } /** * Required - set the event type. These events must correspond with the events from * getEventLabels(). */ public B setType(int type) { mType = type; return mBuilder; } /** * Optional - set the reason why this event was triggered. */ public B setReason(String reason) { mReason = reason; return mBuilder; } } } packages/SystemUI/src/com/android/systemui/log/SysuiLog.java 0 → 100644 +163 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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; import android.os.Build; import android.os.SystemProperties; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.DumpController; import com.android.systemui.Dumpable; import java.io.FileDescriptor; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.ArrayDeque; import java.util.Locale; /** * Thread-safe logger in SystemUI which prints logs to logcat and stores logs to be * printed by the DumpController. This is an alternative to printing directly * to avoid logs being deleted by chatty. The number of logs retained is varied based on * whether the build is {@link Build.IS_DEBUGGABLE}. * * To manually view the logs via adb: * adb shell dumpsys activity service com.android.systemui/.SystemUIService \ * dependency DumpController <SysuiLogId> */ public class SysuiLog implements Dumpable { public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss", Locale.US); private final Object mDataLock = new Object(); private final String mId; private final int mMaxLogs; private boolean mEnabled; @VisibleForTesting protected ArrayDeque<Event> mTimeline; /** * Creates a SysuiLog * To enable or disable logs, set the system property and then restart the device: * adb shell setprop sysui.log.enabled.<id> true/false && adb reboot * @param dumpController where to register this logger's dumpsys * @param id user-readable tag for this logger * @param maxDebugLogs maximum number of logs to retain when {@link sDebuggable} is true * @param maxLogs maximum number of logs to retain when {@link sDebuggable} is false */ public SysuiLog(DumpController dumpController, String id, int maxDebugLogs, int maxLogs) { this(dumpController, id, sDebuggable ? maxDebugLogs : maxLogs, SystemProperties.getBoolean(SYSPROP_ENABLED_PREFIX + id, DEFAULT_ENABLED)); } @VisibleForTesting protected SysuiLog(DumpController dumpController, String id, int maxLogs, boolean enabled) { mId = id; mMaxLogs = maxLogs; mEnabled = enabled; mTimeline = mEnabled ? new ArrayDeque<>(mMaxLogs) : null; dumpController.registerDumpable(mId, this); } public SysuiLog(DumpController dumpController, String id) { this(dumpController, id, DEFAULT_MAX_DEBUG_LOGS, DEFAULT_MAX_LOGS); } /** * Logs an event to the timeline which can be printed by the dumpsys. * May also log to logcat if enabled. * @return true if event was logged, else false */ public boolean log(Event event) { if (!mEnabled) { return false; } synchronized (mDataLock) { if (mTimeline.size() >= mMaxLogs) { mTimeline.removeFirst(); } mTimeline.add(event); } if (LOG_TO_LOGCAT_ENABLED) { final String strEvent = eventToString(event); switch (event.getLogLevel()) { case Event.VERBOSE: Log.v(mId, strEvent); break; case Event.DEBUG: Log.d(mId, strEvent); break; case Event.ERROR: Log.e(mId, strEvent); break; case Event.INFO: Log.i(mId, strEvent); break; case Event.WARN: Log.w(mId, strEvent); break; } } return true; } /** * @return user-readable string of the given event */ public String eventToString(Event event) { StringBuilder sb = new StringBuilder(); sb.append(SysuiLog.DATE_FORMAT.format(event.getTimestamp())); sb.append(" "); sb.append(event.getMessage()); return sb.toString(); } /** * only call on this method if you have the mDataLock */ private void dumpTimelineLocked(PrintWriter pw) { pw.println("\tTimeline:"); for (Event event : mTimeline) { pw.println("\t" + eventToString(event)); } } @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println(mId + ":"); if (mEnabled) { synchronized (mDataLock) { dumpTimelineLocked(pw); } } else { pw.print(" - Logging disabled."); } } private static boolean sDebuggable = Build.IS_DEBUGGABLE; private static final String SYSPROP_ENABLED_PREFIX = "sysui.log.enabled."; private static final boolean LOG_TO_LOGCAT_ENABLED = sDebuggable; private static final boolean DEFAULT_ENABLED = sDebuggable; private static final int DEFAULT_MAX_DEBUG_LOGS = 100; private static final int DEFAULT_MAX_LOGS = 50; } packages/SystemUI/tests/src/com/android/systemui/log/RichEventTest.java 0 → 100644 +69 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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; import static junit.framework.Assert.assertEquals; import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidTestingRunner.class) public class RichEventTest extends SysuiTestCase { private static final int TOTAL_EVENT_TYPES = 1; @Test public void testCreateRichEvent_invalidType() { try { // indexing for events starts at 0, so TOTAL_EVENT_TYPES is an invalid type new TestableRichEvent(Event.DEBUG, TOTAL_EVENT_TYPES, "msg"); } catch (IllegalArgumentException e) { // expected return; } Assert.fail("Expected an invalidArgumentException since the event type was invalid."); } @Test public void testCreateRichEvent() { final int eventType = 0; RichEvent e = new TestableRichEvent(Event.DEBUG, eventType, "msg"); assertEquals(e.getType(), eventType); } class TestableRichEvent extends RichEvent { TestableRichEvent(int logLevel, int type, String reason) { super(logLevel, type, reason); } @Override public String[] getEventLabels() { return new String[]{"ACTION_NAME"}; } } } packages/SystemUI/tests/src/com/android/systemui/log/SysuiLogTest.java 0 → 100644 +82 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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; import static junit.framework.Assert.assertEquals; import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; import com.android.systemui.DumpController; import com.android.systemui.SysuiTestCase; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) public class SysuiLogTest extends SysuiTestCase { private static final String TEST_ID = "TestLogger"; private static final int MAX_LOGS = 5; @Mock private DumpController mDumpController; private SysuiLog mSysuiLog; @Before public void setup() { MockitoAnnotations.initMocks(this); } @Test public void testLogDisabled_noLogsWritten() { mSysuiLog = new SysuiLog(mDumpController, TEST_ID, MAX_LOGS, false); assertEquals(mSysuiLog.mTimeline, null); mSysuiLog.log(new Event("msg")); assertEquals(mSysuiLog.mTimeline, null); } @Test public void testLogEnabled_logWritten() { mSysuiLog = new SysuiLog(mDumpController, TEST_ID, MAX_LOGS, true); assertEquals(mSysuiLog.mTimeline.size(), 0); mSysuiLog.log(new Event("msg")); assertEquals(mSysuiLog.mTimeline.size(), 1); } @Test public void testMaxLogs() { mSysuiLog = new SysuiLog(mDumpController, TEST_ID, MAX_LOGS, true); assertEquals(mSysuiLog.mTimeline.size(), 0); final String msg = "msg"; for (int i = 0; i < MAX_LOGS + 1; i++) { mSysuiLog.log(new Event(msg + i)); } assertEquals(mSysuiLog.mTimeline.size(), MAX_LOGS); // check the first message (msg0) is deleted: assertEquals(mSysuiLog.mTimeline.getFirst().getMessage(), msg + "1"); } } Loading
packages/SystemUI/src/com/android/systemui/log/Event.java 0 → 100644 +67 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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; import android.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Stores information about an event that occurred in SystemUI to be used for debugging and triage. * Every event has a time stamp, log level and message. * Events are stored in {@link SysuiLog} and can be printed in a dumpsys. */ public class Event { public static final int UNINITIALIZED = -1; @IntDef({ERROR, WARN, INFO, DEBUG, VERBOSE}) @Retention(RetentionPolicy.SOURCE) public @interface Level {} public static final int VERBOSE = 2; public static final int DEBUG = 3; public static final int INFO = 4; public static final int WARN = 5; public static final int ERROR = 6; private long mTimestamp; private @Level int mLogLevel = DEBUG; protected String mMessage; public Event(String message) { mTimestamp = System.currentTimeMillis(); mMessage = message; } public Event(@Level int logLevel, String message) { mTimestamp = System.currentTimeMillis(); mLogLevel = logLevel; mMessage = message; } public String getMessage() { return mMessage; } public long getTimestamp() { return mTimestamp; } public @Level int getLogLevel() { return mLogLevel; } }
packages/SystemUI/src/com/android/systemui/log/RichEvent.java 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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; /** * Stores information about an event that occurred in SystemUI to be used for debugging and triage. * Every rich event has a time stamp, event type, and log level, with the option to provide the * reason this event was triggered. * Events are stored in {@link SysuiLog} and can be printed in a dumpsys. */ public abstract class RichEvent extends Event { private final int mType; private final String mReason; /** * Create a rich event that includes an event type that matches with an index in the array * getEventLabels(). */ public RichEvent(@Event.Level int logLevel, int type, String reason) { super(logLevel, null); final int numEvents = getEventLabels().length; if (type < 0 || type >= numEvents) { throw new IllegalArgumentException("Unsupported event type. Events only supported" + " from 0 to " + (numEvents - 1) + ", but given type=" + type); } mType = type; mReason = reason; mMessage = getEventLabels()[mType] + " " + mReason; } /** * Returns an array of the event labels. The index represents the event type and the * corresponding String stored at that index is the user-readable representation of that event. * @return array of user readable events, where the index represents its event type constant */ public abstract String[] getEventLabels(); public int getType() { return mType; } public String getReason() { return mReason; } /** * Builder to build a RichEvent. * @param <B> Log specific builder that is extending this builder */ public abstract static class Builder<B extends Builder<B>> { public static final int UNINITIALIZED = -1; private B mBuilder = getBuilder(); protected int mType = UNINITIALIZED; protected String mReason; protected @Level int mLogLevel; /** * Get the log-specific builder. */ public abstract B getBuilder(); /** * Build the log-specific event. */ public abstract RichEvent build(); /** * Optional - set the log level. Defaults to DEBUG. */ public B setLogLevel(@Level int logLevel) { mLogLevel = logLevel; return mBuilder; } /** * Required - set the event type. These events must correspond with the events from * getEventLabels(). */ public B setType(int type) { mType = type; return mBuilder; } /** * Optional - set the reason why this event was triggered. */ public B setReason(String reason) { mReason = reason; return mBuilder; } } }
packages/SystemUI/src/com/android/systemui/log/SysuiLog.java 0 → 100644 +163 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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; import android.os.Build; import android.os.SystemProperties; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.DumpController; import com.android.systemui.Dumpable; import java.io.FileDescriptor; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.ArrayDeque; import java.util.Locale; /** * Thread-safe logger in SystemUI which prints logs to logcat and stores logs to be * printed by the DumpController. This is an alternative to printing directly * to avoid logs being deleted by chatty. The number of logs retained is varied based on * whether the build is {@link Build.IS_DEBUGGABLE}. * * To manually view the logs via adb: * adb shell dumpsys activity service com.android.systemui/.SystemUIService \ * dependency DumpController <SysuiLogId> */ public class SysuiLog implements Dumpable { public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss", Locale.US); private final Object mDataLock = new Object(); private final String mId; private final int mMaxLogs; private boolean mEnabled; @VisibleForTesting protected ArrayDeque<Event> mTimeline; /** * Creates a SysuiLog * To enable or disable logs, set the system property and then restart the device: * adb shell setprop sysui.log.enabled.<id> true/false && adb reboot * @param dumpController where to register this logger's dumpsys * @param id user-readable tag for this logger * @param maxDebugLogs maximum number of logs to retain when {@link sDebuggable} is true * @param maxLogs maximum number of logs to retain when {@link sDebuggable} is false */ public SysuiLog(DumpController dumpController, String id, int maxDebugLogs, int maxLogs) { this(dumpController, id, sDebuggable ? maxDebugLogs : maxLogs, SystemProperties.getBoolean(SYSPROP_ENABLED_PREFIX + id, DEFAULT_ENABLED)); } @VisibleForTesting protected SysuiLog(DumpController dumpController, String id, int maxLogs, boolean enabled) { mId = id; mMaxLogs = maxLogs; mEnabled = enabled; mTimeline = mEnabled ? new ArrayDeque<>(mMaxLogs) : null; dumpController.registerDumpable(mId, this); } public SysuiLog(DumpController dumpController, String id) { this(dumpController, id, DEFAULT_MAX_DEBUG_LOGS, DEFAULT_MAX_LOGS); } /** * Logs an event to the timeline which can be printed by the dumpsys. * May also log to logcat if enabled. * @return true if event was logged, else false */ public boolean log(Event event) { if (!mEnabled) { return false; } synchronized (mDataLock) { if (mTimeline.size() >= mMaxLogs) { mTimeline.removeFirst(); } mTimeline.add(event); } if (LOG_TO_LOGCAT_ENABLED) { final String strEvent = eventToString(event); switch (event.getLogLevel()) { case Event.VERBOSE: Log.v(mId, strEvent); break; case Event.DEBUG: Log.d(mId, strEvent); break; case Event.ERROR: Log.e(mId, strEvent); break; case Event.INFO: Log.i(mId, strEvent); break; case Event.WARN: Log.w(mId, strEvent); break; } } return true; } /** * @return user-readable string of the given event */ public String eventToString(Event event) { StringBuilder sb = new StringBuilder(); sb.append(SysuiLog.DATE_FORMAT.format(event.getTimestamp())); sb.append(" "); sb.append(event.getMessage()); return sb.toString(); } /** * only call on this method if you have the mDataLock */ private void dumpTimelineLocked(PrintWriter pw) { pw.println("\tTimeline:"); for (Event event : mTimeline) { pw.println("\t" + eventToString(event)); } } @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println(mId + ":"); if (mEnabled) { synchronized (mDataLock) { dumpTimelineLocked(pw); } } else { pw.print(" - Logging disabled."); } } private static boolean sDebuggable = Build.IS_DEBUGGABLE; private static final String SYSPROP_ENABLED_PREFIX = "sysui.log.enabled."; private static final boolean LOG_TO_LOGCAT_ENABLED = sDebuggable; private static final boolean DEFAULT_ENABLED = sDebuggable; private static final int DEFAULT_MAX_DEBUG_LOGS = 100; private static final int DEFAULT_MAX_LOGS = 50; }
packages/SystemUI/tests/src/com/android/systemui/log/RichEventTest.java 0 → 100644 +69 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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; import static junit.framework.Assert.assertEquals; import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidTestingRunner.class) public class RichEventTest extends SysuiTestCase { private static final int TOTAL_EVENT_TYPES = 1; @Test public void testCreateRichEvent_invalidType() { try { // indexing for events starts at 0, so TOTAL_EVENT_TYPES is an invalid type new TestableRichEvent(Event.DEBUG, TOTAL_EVENT_TYPES, "msg"); } catch (IllegalArgumentException e) { // expected return; } Assert.fail("Expected an invalidArgumentException since the event type was invalid."); } @Test public void testCreateRichEvent() { final int eventType = 0; RichEvent e = new TestableRichEvent(Event.DEBUG, eventType, "msg"); assertEquals(e.getType(), eventType); } class TestableRichEvent extends RichEvent { TestableRichEvent(int logLevel, int type, String reason) { super(logLevel, type, reason); } @Override public String[] getEventLabels() { return new String[]{"ACTION_NAME"}; } } }
packages/SystemUI/tests/src/com/android/systemui/log/SysuiLogTest.java 0 → 100644 +82 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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; import static junit.framework.Assert.assertEquals; import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; import com.android.systemui.DumpController; import com.android.systemui.SysuiTestCase; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) public class SysuiLogTest extends SysuiTestCase { private static final String TEST_ID = "TestLogger"; private static final int MAX_LOGS = 5; @Mock private DumpController mDumpController; private SysuiLog mSysuiLog; @Before public void setup() { MockitoAnnotations.initMocks(this); } @Test public void testLogDisabled_noLogsWritten() { mSysuiLog = new SysuiLog(mDumpController, TEST_ID, MAX_LOGS, false); assertEquals(mSysuiLog.mTimeline, null); mSysuiLog.log(new Event("msg")); assertEquals(mSysuiLog.mTimeline, null); } @Test public void testLogEnabled_logWritten() { mSysuiLog = new SysuiLog(mDumpController, TEST_ID, MAX_LOGS, true); assertEquals(mSysuiLog.mTimeline.size(), 0); mSysuiLog.log(new Event("msg")); assertEquals(mSysuiLog.mTimeline.size(), 1); } @Test public void testMaxLogs() { mSysuiLog = new SysuiLog(mDumpController, TEST_ID, MAX_LOGS, true); assertEquals(mSysuiLog.mTimeline.size(), 0); final String msg = "msg"; for (int i = 0; i < MAX_LOGS + 1; i++) { mSysuiLog.log(new Event(msg + i)); } assertEquals(mSysuiLog.mTimeline.size(), MAX_LOGS); // check the first message (msg0) is deleted: assertEquals(mSysuiLog.mTimeline.getFirst().getMessage(), msg + "1"); } }