Add transaction info on ContextHubService dump

=================== TRANSACTIONS ====================
Transaction History:
07/21 19:14:40.707 Load (appId = 0x476f6f6754000004, package = com.google.android.chre.pts.app)
07/21 19:14:39.398 Unload (appId = 0x476f6f6754000003, package = com.google.android.chre.pts.app)
07/21 19:14:37.278 Load (appId = 0x476f6f6754000003, package = com.google.android.chre.pts.app)
07/21 19:14:28.265 Query (package = com.google.uid.shared:10194)
07/21 19:14:15.530 Query (package = com.google.android.apps.scone)
07/21 19:14:12.768 Query (package = com.google.oslo)
07/21 19:14:12.766 Query (package = com.google.oslo)
07/21 19:14:12.763 Query (package = com.google.oslo)
07/21 19:14:12.760 Query (package = com.google.oslo)
07/21 19:14:12.756 Query (package = com.google.oslo)
07/21 19:14:12.753 Query (package = com.google.oslo)
07/21 19:14:11.377 Query (package = android.uid.system:1000)

Bug: 121033022
Test: adb shell dumpsys contexthub
Change-Id: I253ce8d8f74ab06d979f4ab6de141911b30c20b8
This commit is contained in:
Arthur Ishiguro
2020-07-20 14:24:29 -07:00
parent af0f4e817c
commit 400d086072
5 changed files with 174 additions and 56 deletions

View File

@@ -0,0 +1,43 @@
/*
* Copyright 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.
*/
package com.android.server.location;
import java.util.concurrent.ConcurrentLinkedDeque;
/**
* Helper class to make a ConcurrentLinkedDeque fixed-size, evicting old entries when full.
*
* @param <E> The type of elements held in this queue.
*/
public class ConcurrentLinkedEvictingDeque<E> extends ConcurrentLinkedDeque<E> {
private int mSize;
ConcurrentLinkedEvictingDeque(int size) {
mSize = size;
}
@Override
public boolean add(E elem) {
synchronized (this) {
if (size() == mSize) {
poll();
}
return super.add(elem);
}
}
}

View File

@@ -36,7 +36,6 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.function.Consumer;
/**
@@ -103,28 +102,6 @@ import java.util.function.Consumer;
public static final int ACTION_UNREGISTERED = 1;
public static final int ACTION_CANCELLED = 2;
/**
* Helper class to make a ConcurrentLinkedDeque fixed-size, evicting old entries when full.
*/
private class ConcurrentLinkedEvictingDeque<E> extends ConcurrentLinkedDeque<E> {
private int mSize;
ConcurrentLinkedEvictingDeque(int size) {
mSize = size;
}
@Override
public boolean add(E elem) {
synchronized (this) {
if (size() == mSize) {
poll();
}
return super.add(elem);
}
}
}
/**
* A container class to store a record of ContextHubClient registration.
*/

View File

@@ -43,6 +43,7 @@ import android.hardware.location.NanoAppInstanceInfo;
import android.hardware.location.NanoAppMessage;
import android.hardware.location.NanoAppState;
import android.location.LocationManager;
import android.os.Binder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -386,7 +387,7 @@ public class ContextHubService extends IContextHubService.Stub {
createLoadTransactionCallback(contextHubHandle, nanoAppBinary);
ContextHubServiceTransaction transaction = mTransactionManager.createLoadTransaction(
contextHubHandle, nanoAppBinary, onCompleteCallback);
contextHubHandle, nanoAppBinary, onCompleteCallback, getCallingPackageName());
mTransactionManager.addTransaction(transaction);
return 0;
@@ -411,7 +412,7 @@ public class ContextHubService extends IContextHubService.Stub {
IContextHubTransactionCallback onCompleteCallback =
createUnloadTransactionCallback(contextHubId);
ContextHubServiceTransaction transaction = mTransactionManager.createUnloadTransaction(
contextHubId, nanoAppId, onCompleteCallback);
contextHubId, nanoAppId, onCompleteCallback, getCallingPackageName());
mTransactionManager.addTransaction(transaction);
return 0;
@@ -464,7 +465,7 @@ public class ContextHubService extends IContextHubService.Stub {
IContextHubTransactionCallback onCompleteCallback =
createQueryTransactionCallback(contextHubId);
ContextHubServiceTransaction transaction = mTransactionManager.createQueryTransaction(
contextHubId, onCompleteCallback);
contextHubId, onCompleteCallback, getCallingPackageName());
mTransactionManager.addTransaction(transaction);
return Result.OK;
@@ -696,7 +697,7 @@ public class ContextHubService extends IContextHubService.Stub {
}
ContextHubServiceTransaction transaction = mTransactionManager.createLoadTransaction(
contextHubId, nanoAppBinary, transactionCallback);
contextHubId, nanoAppBinary, transactionCallback, getCallingPackageName());
mTransactionManager.addTransaction(transaction);
}
@@ -720,7 +721,7 @@ public class ContextHubService extends IContextHubService.Stub {
}
ContextHubServiceTransaction transaction = mTransactionManager.createUnloadTransaction(
contextHubId, nanoAppId, transactionCallback);
contextHubId, nanoAppId, transactionCallback, getCallingPackageName());
mTransactionManager.addTransaction(transaction);
}
@@ -744,7 +745,7 @@ public class ContextHubService extends IContextHubService.Stub {
}
ContextHubServiceTransaction transaction = mTransactionManager.createEnableTransaction(
contextHubId, nanoAppId, transactionCallback);
contextHubId, nanoAppId, transactionCallback, getCallingPackageName());
mTransactionManager.addTransaction(transaction);
}
@@ -768,7 +769,7 @@ public class ContextHubService extends IContextHubService.Stub {
}
ContextHubServiceTransaction transaction = mTransactionManager.createDisableTransaction(
contextHubId, nanoAppId, transactionCallback);
contextHubId, nanoAppId, transactionCallback, getCallingPackageName());
mTransactionManager.addTransaction(transaction);
}
@@ -790,7 +791,7 @@ public class ContextHubService extends IContextHubService.Stub {
}
ContextHubServiceTransaction transaction = mTransactionManager.createQueryTransaction(
contextHubId, transactionCallback);
contextHubId, transactionCallback, getCallingPackageName());
mTransactionManager.addTransaction(transaction);
}
@@ -822,6 +823,10 @@ public class ContextHubService extends IContextHubService.Stub {
pw.println("=================== CLIENTS ====================");
pw.println(mClientManager);
pw.println("");
pw.println("=================== TRANSACTIONS ====================");
pw.println(mTransactionManager);
// dump eventLog
}
@@ -924,4 +929,8 @@ public class ContextHubService extends IContextHubService.Stub {
mContextHubWrapper.onSettingChanged(Setting.LOCATION,
enabled ? SettingValue.ENABLED : SettingValue.DISABLED);
}
private String getCallingPackageName() {
return mContext.getPackageManager().getNameForUid(Binder.getCallingUid());
}
}

View File

@@ -32,14 +32,32 @@ import java.util.concurrent.TimeUnit;
@ContextHubTransaction.Type
private final int mTransactionType;
/* The ID of the nanoapp this transaction is targeted for, null if not applicable. */
private final Long mNanoAppId;
/*
* The host package associated with this transaction.
*/
private final String mPackage;
/*
* true if the transaction has already completed, false otherwise
*/
private boolean mIsComplete = false;
/* package */ ContextHubServiceTransaction(int id, int type) {
/* package */ ContextHubServiceTransaction(int id, int type, String packageName) {
mTransactionId = id;
mTransactionType = type;
mNanoAppId = null;
mPackage = packageName;
}
/* package */ ContextHubServiceTransaction(int id, int type, long nanoAppId,
String packageName) {
mTransactionId = id;
mTransactionType = type;
mNanoAppId = nanoAppId;
mPackage = packageName;
}
/**
@@ -129,7 +147,13 @@ import java.util.concurrent.TimeUnit;
@Override
public String toString() {
return ContextHubTransaction.typeToString(mTransactionType, true /* upperCase */)
+ " transaction (ID = " + mTransactionId + ")";
String out = ContextHubTransaction.typeToString(mTransactionType, true /* upperCase */)
+ " (";
if (mNanoAppId != null) {
out += "appId = 0x" + Long.toHexString(mNanoAppId) + ", ";
}
out += "package = " + mPackage + ")";
return out;
}
}

View File

@@ -26,11 +26,15 @@ import android.hardware.location.NanoAppState;
import android.os.RemoteException;
import android.util.Log;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayDeque;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@@ -52,6 +56,11 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
private static final int MAX_PENDING_REQUESTS = 10000;
/*
* The DateFormat for printing TransactionRecord.
*/
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd HH:mm:ss.SSS");
/*
* The proxy to talk to the Context Hub
*/
@@ -83,6 +92,33 @@ import java.util.concurrent.atomic.AtomicInteger;
private final ScheduledThreadPoolExecutor mTimeoutExecutor = new ScheduledThreadPoolExecutor(1);
private ScheduledFuture<?> mTimeoutFuture = null;
/*
* The list of previous transaction records.
*/
private static final int NUM_TRANSACTION_RECORDS = 20;
private final ConcurrentLinkedEvictingDeque<TransactionRecord> mTransactionRecordDeque =
new ConcurrentLinkedEvictingDeque<>(NUM_TRANSACTION_RECORDS);
/**
* A container class to store a record of transactions.
*/
private class TransactionRecord {
private final String mTransaction;
private final long mTimestamp;
TransactionRecord(String transaction) {
mTransaction = transaction;
mTimestamp = System.currentTimeMillis();
}
// TODO: Add dump to proto here
@Override
public String toString() {
return DATE_FORMAT.format(new Date(mTimestamp)) + " " + mTransaction;
}
}
/* package */ ContextHubTransactionManager(
IContexthub contextHubProxy, ContextHubClientManager clientManager,
NanoAppStateManager nanoAppStateManager) {
@@ -101,11 +137,12 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
/* package */ ContextHubServiceTransaction createLoadTransaction(
int contextHubId, NanoAppBinary nanoAppBinary,
IContextHubTransactionCallback onCompleteCallback) {
IContextHubTransactionCallback onCompleteCallback, String packageName) {
return new ContextHubServiceTransaction(
mNextAvailableId.getAndIncrement(), ContextHubTransaction.TYPE_LOAD_NANOAPP) {
mNextAvailableId.getAndIncrement(), ContextHubTransaction.TYPE_LOAD_NANOAPP,
nanoAppBinary.getNanoAppId(), packageName) {
@Override
/* package */ int onTransact() {
/* package */ int onTransact() {
android.hardware.contexthub.V1_0.NanoAppBinary hidlNanoAppBinary =
ContextHubServiceUtil.createHidlNanoAppBinary(nanoAppBinary);
try {
@@ -119,7 +156,7 @@ import java.util.concurrent.atomic.AtomicInteger;
}
@Override
/* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
/* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
if (result == ContextHubTransaction.RESULT_SUCCESS) {
// NOTE: The legacy JNI code used to do a query right after a load success
// to synchronize the service cache. Instead store the binary that was
@@ -149,11 +186,13 @@ import java.util.concurrent.atomic.AtomicInteger;
* @return the generated transaction
*/
/* package */ ContextHubServiceTransaction createUnloadTransaction(
int contextHubId, long nanoAppId, IContextHubTransactionCallback onCompleteCallback) {
int contextHubId, long nanoAppId, IContextHubTransactionCallback onCompleteCallback,
String packageName) {
return new ContextHubServiceTransaction(
mNextAvailableId.getAndIncrement(), ContextHubTransaction.TYPE_UNLOAD_NANOAPP) {
mNextAvailableId.getAndIncrement(), ContextHubTransaction.TYPE_UNLOAD_NANOAPP,
nanoAppId, packageName) {
@Override
/* package */ int onTransact() {
/* package */ int onTransact() {
try {
return mContextHubProxy.unloadNanoApp(
contextHubId, nanoAppId, this.getTransactionId());
@@ -165,7 +204,7 @@ import java.util.concurrent.atomic.AtomicInteger;
}
@Override
/* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
/* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
if (result == ContextHubTransaction.RESULT_SUCCESS) {
mNanoAppStateManager.removeNanoAppInstance(contextHubId, nanoAppId);
}
@@ -190,11 +229,13 @@ import java.util.concurrent.atomic.AtomicInteger;
* @return the generated transaction
*/
/* package */ ContextHubServiceTransaction createEnableTransaction(
int contextHubId, long nanoAppId, IContextHubTransactionCallback onCompleteCallback) {
int contextHubId, long nanoAppId, IContextHubTransactionCallback onCompleteCallback,
String packageName) {
return new ContextHubServiceTransaction(
mNextAvailableId.getAndIncrement(), ContextHubTransaction.TYPE_ENABLE_NANOAPP) {
mNextAvailableId.getAndIncrement(), ContextHubTransaction.TYPE_ENABLE_NANOAPP,
packageName) {
@Override
/* package */ int onTransact() {
/* package */ int onTransact() {
try {
return mContextHubProxy.enableNanoApp(
contextHubId, nanoAppId, this.getTransactionId());
@@ -206,7 +247,7 @@ import java.util.concurrent.atomic.AtomicInteger;
}
@Override
/* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
/* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
try {
onCompleteCallback.onTransactionComplete(result);
} catch (RemoteException e) {
@@ -225,11 +266,13 @@ import java.util.concurrent.atomic.AtomicInteger;
* @return the generated transaction
*/
/* package */ ContextHubServiceTransaction createDisableTransaction(
int contextHubId, long nanoAppId, IContextHubTransactionCallback onCompleteCallback) {
int contextHubId, long nanoAppId, IContextHubTransactionCallback onCompleteCallback,
String packageName) {
return new ContextHubServiceTransaction(
mNextAvailableId.getAndIncrement(), ContextHubTransaction.TYPE_DISABLE_NANOAPP) {
mNextAvailableId.getAndIncrement(), ContextHubTransaction.TYPE_DISABLE_NANOAPP,
packageName) {
@Override
/* package */ int onTransact() {
/* package */ int onTransact() {
try {
return mContextHubProxy.disableNanoApp(
contextHubId, nanoAppId, this.getTransactionId());
@@ -241,7 +284,7 @@ import java.util.concurrent.atomic.AtomicInteger;
}
@Override
/* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
/* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
try {
onCompleteCallback.onTransactionComplete(result);
} catch (RemoteException e) {
@@ -259,11 +302,13 @@ import java.util.concurrent.atomic.AtomicInteger;
* @return the generated transaction
*/
/* package */ ContextHubServiceTransaction createQueryTransaction(
int contextHubId, IContextHubTransactionCallback onCompleteCallback) {
int contextHubId, IContextHubTransactionCallback onCompleteCallback,
String packageName) {
return new ContextHubServiceTransaction(
mNextAvailableId.getAndIncrement(), ContextHubTransaction.TYPE_QUERY_NANOAPPS) {
mNextAvailableId.getAndIncrement(), ContextHubTransaction.TYPE_QUERY_NANOAPPS,
packageName) {
@Override
/* package */ int onTransact() {
/* package */ int onTransact() {
try {
return mContextHubProxy.queryApps(contextHubId);
} catch (RemoteException e) {
@@ -273,12 +318,12 @@ import java.util.concurrent.atomic.AtomicInteger;
}
@Override
/* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
/* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
onQueryResponse(result, Collections.emptyList());
}
@Override
/* package */ void onQueryResponse(
/* package */ void onQueryResponse(
@ContextHubTransaction.Result int result, List<NanoAppState> nanoAppStateList) {
try {
onCompleteCallback.onQueryResponse(result, nanoAppStateList);
@@ -307,6 +352,7 @@ import java.util.concurrent.atomic.AtomicInteger;
+ MAX_PENDING_REQUESTS + ")");
}
mTransactionQueue.add(transaction);
mTransactionRecordDeque.add(new TransactionRecord(transaction.toString()));
if (mTransactionQueue.size() == 1) {
startNextTransaction();
@@ -433,4 +479,23 @@ import java.util.concurrent.atomic.AtomicInteger;
}
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(100);
TransactionRecord[] arr;
synchronized (this) {
arr = mTransactionQueue.toArray(new TransactionRecord[0]);
}
for (int i = 0; i < arr.length; i++) {
sb.append(i + ": " + arr[i] + "\n");
}
sb.append("Transaction History:\n");
Iterator<TransactionRecord> iterator = mTransactionRecordDeque.descendingIterator();
while (iterator.hasNext()) {
sb.append(iterator.next() + "\n");
}
return sb.toString();
}
}