[Android Auto] Add USB UEVENT and broadcast intent history in dump_sys

Record all USB Uevent and broadcast intent history in dumpsys.
This will not be covered by other system log and kernel log.

Test: Android Auto team checked
Bug: 186495455
Signed-off-by: Ricky Niu <rickyniu@google.com>
Change-Id: I914969bd67c40f5f56218154521dd48681b6b1dd
This commit is contained in:
Ricky Niu
2021-06-29 17:42:37 +08:00
parent 3d537c48fe
commit f28066d4a4
4 changed files with 164 additions and 2 deletions

View File

@@ -72,6 +72,7 @@ message UsbHandlerProto {
optional bool adb_enabled = 14;
optional string kernel_state = 15;
optional string kernel_function_list = 16;
optional string uevent = 17;
}
message UsbAccessoryProto {
@@ -315,6 +316,7 @@ message UsbProfileGroupSettingsManagerProto {
optional int32 parent_user_id = 1;
repeated UsbSettingsDevicePreferenceProto device_preferences = 2;
repeated UsbSettingsAccessoryPreferenceProto accessory_preferences = 3;
optional string intent = 4;
}
message UsbSettingsDevicePreferenceProto {

View File

@@ -0,0 +1,143 @@
/*
* Copyright (C) 2021 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.server.usb;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.dump.DualDumpOutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.LinkedList;
/**
* Constructor UsbDeviceLogger class
*/
public class UsbDeviceLogger {
private final Object mLock = new Object();
// ring buffer of events to log.
@GuardedBy("mLock")
private final LinkedList<Event> mEvents;
private final String mTitle;
// the maximum number of events to keep in log
private final int mMemSize;
/**
* Constructor for Event class.
*/
public abstract static class Event {
// formatter for timestamps
private static final SimpleDateFormat sFormat = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");
private final Calendar mCalendar;
Event() {
mCalendar = Calendar.getInstance();
}
/**
* Convert event to String
* @return StringBuilder
*/
public String toString() {
return (new StringBuilder(String.format("%tm-%td %tH:%tM:%tS.%tL",
mCalendar, mCalendar, mCalendar, mCalendar, mCalendar, mCalendar)))
.append(" ").append(eventToString()).toString();
}
/**
* Causes the string message for the event to appear in the logcat.
* Here is an example of how to create a new event (a StringEvent), adding it to the logger
* (an instance of UsbDeviceLoggerr) while also making it show in the logcat:
* <pre>
* myLogger.log(
* (new StringEvent("something for logcat and logger")).printLog(MyClass.TAG) );
* </pre>
* @param tag the tag for the android.util.Log.v
* @return the same instance of the event
*/
public Event printLog(String tag) {
Log.i(tag, eventToString());
return this;
}
/**
* Convert event to String.
* This method is only called when the logger history is about to the dumped,
* so this method is where expensive String conversions should be made, not when the Event
* subclass is created.
* Timestamp information will be automatically added, do not include it.
* @return a string representation of the event that occurred.
*/
public abstract String eventToString();
}
/**
* Constructor StringEvent class
*/
public static class StringEvent extends Event {
private final String mMsg;
public StringEvent(String msg) {
mMsg = msg;
}
@Override
public String eventToString() {
return mMsg;
}
}
/**
* Constructor for logger.
* @param size the maximum number of events to keep in log
* @param title the string displayed before the recorded log
*/
public UsbDeviceLogger(int size, String title) {
mEvents = new LinkedList<Event>();
mMemSize = size;
mTitle = title;
}
/**
* Constructor for logger.
* @param evt the maximum number of events to keep in log
*/
public synchronized void log(Event evt) {
synchronized (mLock) {
if (mEvents.size() >= mMemSize) {
mEvents.removeFirst();
}
mEvents.add(evt);
}
}
/**
* Constructor for logger.
* @param dump the maximum number of events to keep in log
* @param id the category of events
*/
public synchronized void dump(DualDumpOutputStream dump, long id) {
dump.write("USB Event Log", id, mTitle);
for (Event evt : mEvents) {
dump.write("USB Event", id, evt.toString());
}
}
}

View File

@@ -191,6 +191,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
*/
private static final int ACCESSORY_HANDSHAKE_TIMEOUT = 10 * 1000;
private static final int DUMPSYS_LOG_BUFFER = 200;
private static final String BOOT_MODE_PROPERTY = "ro.bootmode";
private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv";
@@ -210,6 +212,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
private static Set<Integer> sDenyInterfaces;
private HashMap<Long, FileDescriptor> mControlFds;
private static UsbDeviceLogger sEventLogger;
static {
sDenyInterfaces = new HashSet<>();
sDenyInterfaces.add(UsbConstants.USB_CLASS_AUDIO);
@@ -232,9 +236,11 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
@Override
public void onUEvent(UEventObserver.UEvent event) {
if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString());
sEventLogger.log(new UsbDeviceLogger.StringEvent("USB UEVENT: " + event.toString()));
String state = event.get("USB_STATE");
String accessory = event.get("ACCESSORY");
if (state != null) {
mHandler.updateState(state);
} else if ("GETPROTOCOL".equals(accessory)) {
@@ -382,6 +388,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
mUEventObserver = new UsbUEventObserver();
mUEventObserver.startObserving(USB_STATE_MATCH);
mUEventObserver.startObserving(ACCESSORY_START_MATCH);
sEventLogger = new UsbDeviceLogger(DUMPSYS_LOG_BUFFER, "UsbDeviceManager activity");
}
UsbProfileGroupSettingsManager getCurrentSettings() {
@@ -814,6 +822,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
protected void sendStickyBroadcast(Intent intent) {
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
sEventLogger.log(new UsbDeviceLogger.StringEvent("USB intent: " + intent));
}
private void updateUsbFunctions() {
@@ -2285,6 +2294,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
if (mHandler != null) {
mHandler.dump(dump, "handler", UsbDeviceManagerProto.HANDLER);
sEventLogger.dump(dump, UsbHandlerProto.UEVENT);
}
dump.end(token);

View File

@@ -60,7 +60,6 @@ import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.Immutable;
import com.android.internal.content.PackageMonitor;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.dump.DualDumpOutputStream;
@@ -75,7 +74,6 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ProtocolException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -86,6 +84,8 @@ class UsbProfileGroupSettingsManager {
private static final String TAG = UsbProfileGroupSettingsManager.class.getSimpleName();
private static final boolean DEBUG = false;
private static final int DUMPSYS_LOG_BUFFER = 200;
/** Legacy settings file, before multi-user */
private static final File sSingleUserSettingsFile = new File(
"/data/system/usb_device_manager.xml");
@@ -130,6 +130,8 @@ class UsbProfileGroupSettingsManager {
@GuardedBy("mLock")
private boolean mIsWriteSettingsScheduled;
private static UsbDeviceLogger sEventLogger;
/**
* A package of a user.
*/
@@ -260,6 +262,9 @@ class UsbProfileGroupSettingsManager {
device, false /* showMtpNotification */));
mUsbHandlerManager = usbResolveActivityManager;
sEventLogger = new UsbDeviceLogger(DUMPSYS_LOG_BUFFER,
"UsbProfileGroupSettingsManager activity");
}
/**
@@ -965,6 +970,7 @@ class UsbProfileGroupSettingsManager {
matches, mAccessoryPreferenceMap.get(new AccessoryFilter(accessory)));
}
sEventLogger.log(new UsbDeviceLogger.StringEvent("accessoryAttached: " + intent));
resolveActivity(intent, matches, defaultActivity, null, accessory);
}
@@ -1518,6 +1524,7 @@ class UsbProfileGroupSettingsManager {
}
}
sEventLogger.dump(dump, UsbProfileGroupSettingsManagerProto.INTENT);
dump.end(token);
}