Merge "Bug fix for crashing FGS type logger" into udc-dev

This commit is contained in:
Kunal Malhotra
2023-05-24 03:51:10 +00:00
committed by Android (Google) Code Review

View File

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