diff options
7 files changed, 225 insertions, 10 deletions
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java index a11f2e9e8373..6d56d2d45922 100644 --- a/core/java/android/hardware/location/ContextHubInfo.java +++ b/core/java/android/hardware/location/ContextHubInfo.java @@ -21,6 +21,7 @@ import android.annotation.SystemApi; import android.hardware.contexthub.V1_0.ContextHub; import android.os.Parcel; import android.os.Parcelable; +import android.util.proto.ProtoOutputStream; import java.util.Arrays; @@ -270,6 +271,30 @@ public class ContextHubInfo implements Parcelable { return retVal; } + /** + * Dump the internal state as a ContextHubInfoProto to the given ProtoOutputStream. + * + * If the output belongs to a sub message, the caller is responsible for wrapping this function + * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}. + * + * @hide + */ + public void dump(ProtoOutputStream proto) { + proto.write(ContextHubInfoProto.ID, mId); + proto.write(ContextHubInfoProto.NAME, mName); + proto.write(ContextHubInfoProto.VENDOR, mVendor); + proto.write(ContextHubInfoProto.TOOLCHAIN, mToolchain); + proto.write(ContextHubInfoProto.PLATFORM_VERSION, mPlatformVersion); + proto.write(ContextHubInfoProto.STATIC_SW_VERSION, getStaticSwVersion()); + proto.write(ContextHubInfoProto.TOOLCHAIN_VERSION, mToolchainVersion); + proto.write(ContextHubInfoProto.CHRE_PLATFORM_ID, mChrePlatformId); + proto.write(ContextHubInfoProto.PEAK_MIPS, mPeakMips); + proto.write(ContextHubInfoProto.STOPPED_POWER_DRAW_MW, mStoppedPowerDrawMw); + proto.write(ContextHubInfoProto.SLEEP_POWER_DRAW_MW, mSleepPowerDrawMw); + proto.write(ContextHubInfoProto.PEAK_POWER_DRAW_MW, mPeakPowerDrawMw); + proto.write(ContextHubInfoProto.MAX_PACKET_LENGTH_BYTES, mMaxPacketLengthBytes); + } + @Override public boolean equals(@Nullable Object object) { if (object == this) { diff --git a/core/proto/android/hardware/location/context_hub_info.proto b/core/proto/android/hardware/location/context_hub_info.proto new file mode 100644 index 000000000000..de5cd55fafaf --- /dev/null +++ b/core/proto/android/hardware/location/context_hub_info.proto @@ -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 android.hardware.location; + +import "frameworks/base/core/proto/android/privacy.proto"; + +option java_multiple_files = true; + +message ContextHubInfoProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + // Context hub unique identifier + optional int32 id = 1; + // A name for the hub + optional string name = 2; + // A name for the vendor + optional string vendor = 3; + // Description of the tool chain + optional string toolchain = 4; + optional int32 platform_version = 5; + optional int32 static_sw_version = 6; + optional int32 toolchain_version = 7; + // The CHRE platform ID as defined in chre/version.h + optional int64 chre_platform_id = 8; + // Peak MIPS that this hub can deliver + optional float peak_mips = 9; + // Power draw in stopped state in milli watts + optional float stopped_power_draw_mw = 10; + // Power draw in sleep state in milli watts + optional float sleep_power_draw_mw = 11; + // Peak power draw in milli watts + optional float peak_power_draw_mw = 12; + // The maximum number of bytes that can be sent per message to the hub + optional int32 max_packet_length_bytes = 13; +} diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto index d08cbed5909d..8adcc9ed905d 100644 --- a/core/proto/android/os/incident.proto +++ b/core/proto/android/os/incident.proto @@ -36,6 +36,7 @@ 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/fingerprint.proto"; import "frameworks/base/core/proto/android/server/jobscheduler.proto"; +import "frameworks/base/core/proto/android/server/location/context_hub.proto"; import "frameworks/base/core/proto/android/server/powermanagerservice.proto"; import "frameworks/base/core/proto/android/server/rolemanagerservice.proto"; import "frameworks/base/core/proto/android/server/windowmanagerservice.proto"; @@ -486,6 +487,11 @@ message IncidentProto { (section).args = "connmetrics --proto" ]; + optional com.android.server.location.ContextHubServiceProto context_hub = 3051 [ + (section).type = SECTION_DUMPSYS, + (section).args = "contexthub --proto" + ]; + // Reserved for OEMs. extensions 50000 to 100000; } diff --git a/core/proto/android/server/location/context_hub.proto b/core/proto/android/server/location/context_hub.proto new file mode 100644 index 000000000000..c87f79193ee3 --- /dev/null +++ b/core/proto/android/server/location/context_hub.proto @@ -0,0 +1,60 @@ +/* + * 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.location; + +import "frameworks/base/core/proto/android/hardware/location/context_hub_info.proto"; +import "frameworks/base/core/proto/android/privacy.proto"; + +option java_multiple_files = true; + +message ContextHubServiceProto { + option (.android.msg_privacy).dest = DEST_AUTOMATIC; + + repeated .android.hardware.location.ContextHubInfoProto context_hub_info = 1; + optional ClientManagerProto client_manager = 2; +} + +message ClientManagerProto { + option (.android.msg_privacy).dest = DEST_AUTOMATIC; + + message RegistrationRecord { + option (.android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int64 timestamp_ms = 1; + optional int32 action = 2; + // ClientBroker endpoint id, contexthub id and package name + optional string broker = 3; + } + + repeated ClientBrokerProto client_brokers = 1; + repeated RegistrationRecord registration_records = 2; +} + +message ClientBrokerProto { + option (.android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 endpoint_id = 1; + optional int32 attached_context_hub_id = 2; + optional string package = 3; + optional int64 nano_app_id = 4; + optional bool pending_intent_request_valid = 5; + optional bool has_pending_intent = 6; + optional bool pending_intent_cancelled = 7; + optional bool registered = 8; + +} diff --git a/services/core/java/com/android/server/location/ContextHubClientBroker.java b/services/core/java/com/android/server/location/ContextHubClientBroker.java index 45d9bae23e26..bb96e985cf53 100644 --- a/services/core/java/com/android/server/location/ContextHubClientBroker.java +++ b/services/core/java/com/android/server/location/ContextHubClientBroker.java @@ -33,6 +33,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; +import android.util.proto.ProtoOutputStream; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @@ -449,6 +450,28 @@ public class ContextHubClientBroker extends IContextHubClient.Stub } } + /** + * Dump debugging info as ClientBrokerProto + * + * If the output belongs to a sub message, the caller is responsible for wrapping this function + * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}. + * + * @param proto the ProtoOutputStream to write to + */ + void dump(ProtoOutputStream proto) { + proto.write(ClientBrokerProto.ENDPOINT_ID, getHostEndPointId()); + proto.write(ClientBrokerProto.ATTACHED_CONTEXT_HUB_ID, getAttachedContextHubId()); + proto.write(ClientBrokerProto.PACKAGE, mPackage); + if (mPendingIntentRequest.isValid()) { + proto.write(ClientBrokerProto.PENDING_INTENT_REQUEST_VALID, true); + proto.write(ClientBrokerProto.NANO_APP_ID, mPendingIntentRequest.getNanoAppId()); + } + proto.write(ClientBrokerProto.HAS_PENDING_INTENT, mPendingIntentRequest.hasPendingIntent()); + proto.write(ClientBrokerProto.PENDING_INTENT_CANCELLED, isPendingIntentCancelled()); + proto.write(ClientBrokerProto.REGISTERED, mRegistered); + + } + @Override public String toString() { String out = "[ContextHubClient "; diff --git a/services/core/java/com/android/server/location/ContextHubClientManager.java b/services/core/java/com/android/server/location/ContextHubClientManager.java index 46db8dc5dd77..0f70bb8bc840 100644 --- a/services/core/java/com/android/server/location/ContextHubClientManager.java +++ b/services/core/java/com/android/server/location/ContextHubClientManager.java @@ -27,10 +27,13 @@ import android.hardware.location.IContextHubClientCallback; import android.hardware.location.NanoAppMessage; import android.os.RemoteException; import android.util.Log; +import android.util.proto.ProtoOutputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.Calendar; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; @@ -45,6 +48,11 @@ import java.util.function.Consumer; private static final String TAG = "ContextHubClientManager"; /* + * The DateFormat for printing RegistrationRecord. + */ + private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd HH:mm:ss.SSS"); + + /* * The maximum host endpoint ID value that a client can be assigned. */ private static final int MAX_CLIENT_ID = 0x7fff; @@ -123,24 +131,24 @@ import java.util.function.Consumer; private class RegistrationRecord { private final String mBroker; private final int mAction; - private final String mDate; + private final long mTimestamp; RegistrationRecord(String broker, @Action int action) { mBroker = broker; mAction = action; - Calendar instance = Calendar.getInstance(); - mDate = String.format("%02d", instance.get(Calendar.MONTH) + 1) // Jan == 0 - + "/" + String.format("%02d", instance.get(Calendar.DAY_OF_MONTH)) - + " " + String.format("%02d", instance.get(Calendar.HOUR_OF_DAY)) - + ":" + String.format("%02d", instance.get(Calendar.MINUTE)) - + ":" + String.format("%02d", instance.get(Calendar.SECOND)) - + "." + String.format("%03d", instance.get(Calendar.MILLISECOND)); + mTimestamp = System.currentTimeMillis(); + } + + void dump(ProtoOutputStream proto) { + proto.write(ClientManagerProto.RegistrationRecord.TIMESTAMP_MS, mTimestamp); + proto.write(ClientManagerProto.RegistrationRecord.ACTION, mAction); + proto.write(ClientManagerProto.RegistrationRecord.BROKER, mBroker); } @Override public String toString() { String out = ""; - out += mDate + " "; + out += DATE_FORMAT.format(new Date(mTimestamp)) + " "; out += mAction == ACTION_REGISTERED ? "+ " : "- "; out += mBroker; if (mAction == ACTION_CANCELLED) { @@ -376,6 +384,28 @@ import java.util.function.Consumer; return null; } + /** + * Dump debugging info as ClientManagerProto + * + * If the output belongs to a sub message, the caller is responsible for wrapping this function + * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}. + * + * @param proto the ProtoOutputStream to write to + */ + void dump(ProtoOutputStream proto) { + for (ContextHubClientBroker broker : mHostEndPointIdToClientMap.values()) { + long token = proto.start(ClientManagerProto.CLIENT_BROKERS); + broker.dump(proto); + proto.end(token); + } + Iterator<RegistrationRecord> it = mRegistrationRecordDeque.descendingIterator(); + while (it.hasNext()) { + long token = proto.start(ClientManagerProto.REGISTRATION_RECORDS); + it.next().dump(proto); + proto.end(token); + } + } + @Override public String toString() { String out = ""; diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java index 787a8007920d..e79eddf247cb 100644 --- a/services/core/java/com/android/server/location/ContextHubService.java +++ b/services/core/java/com/android/server/location/ContextHubService.java @@ -43,6 +43,7 @@ import android.hardware.location.NanoAppState; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.util.Log; +import android.util.proto.ProtoOutputStream; import com.android.internal.util.DumpUtils; @@ -782,6 +783,13 @@ public class ContextHubService extends IContextHubService.Stub { protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; + for (String arg : args) { + if ("--proto".equals(arg)) { + dump(new ProtoOutputStream(fd)); + return; + } + } + pw.println("Dumping ContextHub Service"); pw.println(""); @@ -802,6 +810,20 @@ public class ContextHubService extends IContextHubService.Stub { // dump eventLog } + private void dump(ProtoOutputStream proto) { + mContextHubIdToInfoMap.values().forEach(hubInfo -> { + long token = proto.start(ContextHubServiceProto.CONTEXT_HUB_INFO); + hubInfo.dump(proto); + proto.end(token); + }); + + long token = proto.start(ContextHubServiceProto.CLIENT_MANAGER); + mClientManager.dump(proto); + proto.end(token); + + proto.flush(); + } + private void checkPermissions() { ContextHubServiceUtil.checkPermissions(mContext); } |