Bug fix for crashing FGS type logger
Test: manual testing on device and unit testing (atest FgsLoggerTest) Bug: 277583461 Change-Id: Icdf145edb0b2a7eeb8c458d0d4a43c34785958d9
This commit is contained in:
@@ -34,8 +34,11 @@ import android.app.ForegroundServiceDelegationOptions;
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.IntArray;
|
||||
import android.util.LongArray;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
@@ -90,13 +93,13 @@ public class ForegroundServiceTypeLoggerModule {
|
||||
// These counts will only be added to the open call count below if
|
||||
// an FGS is started. If an FGS is NOT started, then this count should
|
||||
// gradually hit zero as close calls are decremented.
|
||||
final SparseArray<Integer> mOpenedWithoutFgsCount = new SparseArray<>();
|
||||
final SparseIntArray mOpenedWithoutFgsCount = new SparseIntArray();
|
||||
|
||||
// Here we keep track of the count of in-flight calls.
|
||||
// We only want to log the first open call and the last
|
||||
// close call so that we get the largest duration
|
||||
// possible.
|
||||
final SparseArray<Integer> mOpenWithFgsCount = new SparseArray<>();
|
||||
final SparseIntArray mOpenWithFgsCount = new SparseIntArray();
|
||||
|
||||
// A stack that keeps a list of API calls in the order
|
||||
// that they were called. This represents the ongoing
|
||||
@@ -131,12 +134,12 @@ public class ForegroundServiceTypeLoggerModule {
|
||||
mUids.put(uid, uidState);
|
||||
}
|
||||
// grab the appropriate types
|
||||
final ArrayList<Integer> apiTypes =
|
||||
final IntArray apiTypes =
|
||||
convertFgsTypeToApiTypes(record.foregroundServiceType);
|
||||
// now we need to iterate through the types
|
||||
// and insert the new record as needed
|
||||
final ArrayList<Integer> apiTypesFound = new ArrayList<>();
|
||||
final ArrayList<Long> timestampsFound = new ArrayList<>();
|
||||
final IntArray apiTypesFound = new IntArray();
|
||||
final LongArray timestampsFound = new LongArray();
|
||||
for (int i = 0, size = apiTypes.size(); i < size; i++) {
|
||||
final int apiType = apiTypes.get(i);
|
||||
int fgsIndex = uidState.mRunningFgs.indexOfKey(apiType);
|
||||
@@ -170,7 +173,7 @@ public class ForegroundServiceTypeLoggerModule {
|
||||
uidState.mApiOpenCalls.remove(apiType);
|
||||
}
|
||||
}
|
||||
if (!apiTypesFound.isEmpty()) {
|
||||
if (apiTypesFound.size() != 0) {
|
||||
// log a state change
|
||||
for (int i = 0, size = apiTypesFound.size(); i < size; i++) {
|
||||
logFgsApiEvent(record,
|
||||
@@ -190,7 +193,7 @@ public class ForegroundServiceTypeLoggerModule {
|
||||
// we need to log all the API end events and remove the start events
|
||||
// then we remove the FGS from the various stacks
|
||||
// and also clean up the start calls stack by UID
|
||||
final ArrayList<Integer> apiTypes = convertFgsTypeToApiTypes(record.foregroundServiceType);
|
||||
final IntArray apiTypes = convertFgsTypeToApiTypes(record.foregroundServiceType);
|
||||
final UidState uidState = mUids.get(uid);
|
||||
if (uidState == null) {
|
||||
Slog.w(TAG, "FGS stop call being logged with no start call for UID for UID "
|
||||
@@ -202,7 +205,8 @@ public class ForegroundServiceTypeLoggerModule {
|
||||
final ArrayList<Long> timestampsFound = new ArrayList<>();
|
||||
for (int i = 0, size = apiTypes.size(); i < size; i++) {
|
||||
final int apiType = apiTypes.get(i);
|
||||
if (!uidState.mOpenWithFgsCount.contains(apiType)) {
|
||||
final int apiTypeIndex = uidState.mOpenWithFgsCount.indexOfKey(apiType);
|
||||
if (apiTypeIndex < 0) {
|
||||
Slog.w(TAG, "Logger should be tracking FGS types correctly for UID " + uid
|
||||
+ " in package " + record.packageName);
|
||||
continue;
|
||||
@@ -213,7 +217,7 @@ public class ForegroundServiceTypeLoggerModule {
|
||||
// we just skip logging
|
||||
final FgsApiRecord closedApi = uidState.mApiClosedCalls.get(apiType);
|
||||
if (closedApi != null
|
||||
&& uidState.mOpenWithFgsCount.get(apiType) == 0) {
|
||||
&& uidState.mOpenWithFgsCount.valueAt(apiTypeIndex) == 0) {
|
||||
apisFound.add(apiType);
|
||||
timestampsFound.add(closedApi.mTimeStart);
|
||||
// remove the last API close call
|
||||
@@ -332,7 +336,8 @@ public class ForegroundServiceTypeLoggerModule {
|
||||
Slog.w(TAG, "API event end called before start!");
|
||||
return -1;
|
||||
}
|
||||
if (uidState.mOpenWithFgsCount.contains(apiType)) {
|
||||
final int apiIndex = uidState.mOpenWithFgsCount.indexOfKey(apiType);
|
||||
if (apiIndex >= 0) {
|
||||
// are there any calls that started with an FGS?
|
||||
if (uidState.mOpenWithFgsCount.get(apiType) != 0) {
|
||||
// we should decrement the count, since we only
|
||||
@@ -351,7 +356,7 @@ public class ForegroundServiceTypeLoggerModule {
|
||||
logFgsApiEventWithNoFgs(uid, FGS_API_END_WITHOUT_FGS, apiTypes, timestamp);
|
||||
// we should now remove the count, so as to signal that
|
||||
// there was never an FGS called that can be associated
|
||||
uidState.mOpenWithFgsCount.remove(apiType);
|
||||
uidState.mOpenWithFgsCount.removeAt(apiIndex);
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
@@ -359,7 +364,7 @@ public class ForegroundServiceTypeLoggerModule {
|
||||
// open FGS associated API call. So it is likely
|
||||
// a part of an unassociated call that has now been
|
||||
// closed. So we decrement that count
|
||||
if (!uidState.mOpenedWithoutFgsCount.contains(apiType)) {
|
||||
if (uidState.mOpenedWithoutFgsCount.indexOfKey(apiType) < 0) {
|
||||
// initialize if we don't contain
|
||||
uidState.mOpenedWithoutFgsCount.put(apiType, 0);
|
||||
}
|
||||
@@ -402,8 +407,8 @@ public class ForegroundServiceTypeLoggerModule {
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<Integer> convertFgsTypeToApiTypes(int fgsType) {
|
||||
final ArrayList<Integer> types = new ArrayList<>();
|
||||
private IntArray convertFgsTypeToApiTypes(int fgsType) {
|
||||
final IntArray types = new IntArray();
|
||||
if ((fgsType & ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA)
|
||||
== ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA) {
|
||||
types.add(FOREGROUND_SERVICE_API_TYPE_CAMERA);
|
||||
|
||||
Reference in New Issue
Block a user