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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user