Implement dumpsys bluetooth_manager --proto

Add BluetoothManagerServiceDumpProto for protobuf dumpsys of bluetooth
manager service. Primarily used by incident service to capture an
incident report proto.

Command to invoke (any of the following after lunch and env setup):
$ adb shell dumpsys bluetooth_manager --proto
$ adb shell incident 3050
$ incident_report 3050

Bug: 146085372
Test: Execute the above commands and compare the output against normal
dumpsys

Change-Id: I7ccef334ffeae02316db3afff929998b544972b1
This commit is contained in:
Mike Ma
2020-02-12 13:07:47 -08:00
parent 53e0762358
commit 2781d0b2d2
3 changed files with 137 additions and 47 deletions

View File

@@ -34,6 +34,7 @@ import "frameworks/base/core/proto/android/os/system_properties.proto";
import "frameworks/base/core/proto/android/providers/settings.proto";
import "frameworks/base/core/proto/android/server/activitymanagerservice.proto";
import "frameworks/base/core/proto/android/server/alarmmanagerservice.proto";
import "frameworks/base/core/proto/android/server/bluetooth_manager_service.proto";
import "frameworks/base/core/proto/android/server/fingerprint.proto";
import "frameworks/base/core/proto/android/server/jobscheduler.proto";
import "frameworks/base/core/proto/android/server/location/context_hub.proto";
@@ -488,6 +489,11 @@ message IncidentProto {
(section).args = "connmetrics --proto"
];
optional com.android.server.BluetoothManagerServiceDumpProto bluetooth_manager = 3050 [
(section).type = SECTION_DUMPSYS,
(section).args = "bluetooth_manager --proto"
];
optional com.android.server.location.ContextHubServiceProto context_hub = 3051 [
(section).type = SECTION_DUMPSYS,
(section).args = "contexthub --proto"

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2020 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.
*/
syntax = "proto2";
package com.android.server;
import "frameworks/base/core/proto/android/bluetooth/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
option java_multiple_files = true;
message BluetoothManagerServiceDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
message ActiveLog {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional int64 timestamp_ms = 1;
optional bool enable = 2;
optional string package_name = 3;
optional .android.bluetooth.EnableDisableReasonEnum reason = 4;
}
optional bool enabled = 1;
optional int32 state = 2;
optional string state_name = 3;
optional string address = 4 [(.android.privacy).dest = DEST_EXPLICIT];
optional string name = 5 [(.android.privacy).dest = DEST_EXPLICIT];
optional int64 last_enabled_time_ms = 6;
optional int64 curr_timestamp_ms = 7;
repeated ActiveLog active_logs = 8;
optional int32 num_crashes = 9;
optional bool crash_log_maxed = 10;
repeated int64 crash_timestamps_ms = 11;
optional int32 num_ble_apps = 12;
repeated string ble_app_package_names = 13;
}

View File

@@ -69,6 +69,7 @@ import android.text.TextUtils;
import android.util.FeatureFlagUtils;
import android.util.Log;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -196,6 +197,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
+ " due to " + getEnableDisableReasonString(mReason) + " by " + mPackageName;
}
void dump(ProtoOutputStream proto) {
proto.write(BluetoothManagerServiceDumpProto.ActiveLog.TIMESTAMP_MS, mTimestamp);
proto.write(BluetoothManagerServiceDumpProto.ActiveLog.ENABLE, mEnable);
proto.write(BluetoothManagerServiceDumpProto.ActiveLog.PACKAGE_NAME, mPackageName);
proto.write(BluetoothManagerServiceDumpProto.ActiveLog.REASON, mReason);
}
}
private final LinkedList<ActiveLog> mActiveLogs = new LinkedList<>();
@@ -2408,56 +2415,56 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) {
return;
}
if ((args.length > 0) && args[0].startsWith("--proto")) {
dumpProto(fd);
return;
}
String errorMsg = null;
boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
writer.println("Bluetooth Status");
writer.println(" enabled: " + isEnabled());
writer.println(" state: " + BluetoothAdapter.nameForState(mState));
writer.println(" address: " + mAddress);
writer.println(" name: " + mName);
if (mEnable) {
long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
(int) (onDuration / (1000 * 60 * 60)),
(int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
(int) (onDuration % 1000));
writer.println(" time since enabled: " + onDurationString);
}
if (!protoOut) {
writer.println("Bluetooth Status");
writer.println(" enabled: " + isEnabled());
writer.println(" state: " + BluetoothAdapter.nameForState(mState));
writer.println(" address: " + mAddress);
writer.println(" name: " + mName);
if (mEnable) {
long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
(int) (onDuration / (1000 * 60 * 60)),
(int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
(int) (onDuration % 1000));
writer.println(" time since enabled: " + onDurationString);
if (mActiveLogs.size() == 0) {
writer.println("\nBluetooth never enabled!");
} else {
writer.println("\nEnable log:");
for (ActiveLog log : mActiveLogs) {
writer.println(" " + log);
}
}
if (mActiveLogs.size() == 0) {
writer.println("\nBluetooth never enabled!");
} else {
writer.println("\nEnable log:");
for (ActiveLog log : mActiveLogs) {
writer.println(" " + log);
}
}
writer.println(
"\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
if (mCrashes == CRASH_LOG_MAX_SIZE) {
writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
}
for (Long time : mCrashTimestamps) {
writer.println(" " + timeToLog(time));
}
writer.println(
"\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
if (mCrashes == CRASH_LOG_MAX_SIZE) {
writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
}
for (Long time : mCrashTimestamps) {
writer.println(" " + timeToLog(time));
}
writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
+ " registered");
for (ClientDeathRecipient app : mBleApps.values()) {
writer.println(" " + app.getPackageName());
}
writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
+ "registered");
for (ClientDeathRecipient app : mBleApps.values()) {
writer.println(" " + app.getPackageName());
}
writer.println("");
writer.flush();
if (args.length == 0) {
// Add arg to produce output
args = new String[1];
args[0] = "--print";
}
writer.println("");
writer.flush();
if (args.length == 0) {
// Add arg to produce output
args = new String[1];
args[0] = "--print";
}
if (mBluetoothBinder == null) {
@@ -2470,14 +2477,42 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
}
if (errorMsg != null) {
// Silently return if we are extracting metrics in Protobuf format
if (protoOut) {
return;
}
writer.println(errorMsg);
}
}
private void dumpProto(FileDescriptor fd) {
final ProtoOutputStream proto = new ProtoOutputStream(fd);
proto.write(BluetoothManagerServiceDumpProto.ENABLED, isEnabled());
proto.write(BluetoothManagerServiceDumpProto.STATE, mState);
proto.write(BluetoothManagerServiceDumpProto.STATE_NAME,
BluetoothAdapter.nameForState(mState));
proto.write(BluetoothManagerServiceDumpProto.ADDRESS, mAddress);
proto.write(BluetoothManagerServiceDumpProto.NAME, mName);
if (mEnable) {
proto.write(BluetoothManagerServiceDumpProto.LAST_ENABLED_TIME_MS, mLastEnabledTime);
}
proto.write(BluetoothManagerServiceDumpProto.CURR_TIMESTAMP_MS,
SystemClock.elapsedRealtime());
for (ActiveLog log : mActiveLogs) {
long token = proto.start(BluetoothManagerServiceDumpProto.ACTIVE_LOGS);
log.dump(proto);
proto.end(token);
}
proto.write(BluetoothManagerServiceDumpProto.NUM_CRASHES, mCrashes);
proto.write(BluetoothManagerServiceDumpProto.CRASH_LOG_MAXED,
mCrashes == CRASH_LOG_MAX_SIZE);
for (Long time : mCrashTimestamps) {
proto.write(BluetoothManagerServiceDumpProto.CRASH_TIMESTAMPS_MS, time);
}
proto.write(BluetoothManagerServiceDumpProto.NUM_BLE_APPS, mBleApps.size());
for (ClientDeathRecipient app : mBleApps.values()) {
proto.write(BluetoothManagerServiceDumpProto.BLE_APP_PACKAGE_NAMES,
app.getPackageName());
}
proto.flush();
}
private static String getEnableDisableReasonString(int reason) {
switch (reason) {
case BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST: