Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5988bb5c authored by Kunal Malhotra's avatar Kunal Malhotra
Browse files

Bug fix for crashing FGS type logger

Test: manual testing on device and unit testing (atest
FgsLoggerTest)
Bug: 277583461

Change-Id: Icdf145edb0b2a7eeb8c458d0d4a43c34785958d9
parent 388b57a0
Loading
Loading
Loading
Loading
+19 −14
Original line number Diff line number Diff line
@@ -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);