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

Commit 5fc0875d authored by Kunal Malhotra's avatar Kunal Malhotra Committed by Automerger Merge Worker
Browse files

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

parents 1afe4478 64941906
Loading
Loading
Loading
Loading
+19 −14
Original line number Original line Diff line number Diff line
@@ -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);