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

Commit e0856207 authored by Kriti Dang's avatar Kriti Dang Committed by Android (Google) Code Review
Browse files

Merge "Fetch display metrics"

parents 20638237 d1a1f36d
Loading
Loading
Loading
Loading
+124 −12
Original line number Diff line number Diff line
@@ -93,9 +93,12 @@ import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.display.DisplayManager;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.media.AudioManager;
import android.media.MediaDrm;
import android.media.UnsupportedSchemeException;
import android.net.ConnectivityManager;
import android.net.INetworkStatsService;
import android.net.INetworkStatsSession;
@@ -164,6 +167,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.StatsEvent;
import android.util.proto.ProtoOutputStream;
import android.view.Display;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.procstats.IProcessStats;
@@ -4492,10 +4496,8 @@ public class StatsPullAtomService extends SystemService {

        // get the surround sound metrics information
        Map<Integer, Boolean> surroundEncodingsMap = audioManager.getSurroundFormats();
        byte[] surroundEncodings =
                getAudioEncodingsAsProto(new ArrayList(surroundEncodingsMap.keySet()));
        byte[] sinkSurroundEncodings =
                getAudioEncodingsAsProto(audioManager.getReportedSurroundFormats());
        byte[] surroundEncodings = toBytes(new ArrayList(surroundEncodingsMap.keySet()));
        byte[] sinkSurroundEncodings = toBytes(audioManager.getReportedSurroundFormats());
        List<Integer> disabledSurroundEncodingsList = new ArrayList<>();
        List<Integer> enabledSurroundEncodingsList = new ArrayList<>();
        for (int surroundEncoding:  surroundEncodingsMap.keySet()) {
@@ -4505,24 +4507,68 @@ public class StatsPullAtomService extends SystemService {
                enabledSurroundEncodingsList.add(surroundEncoding);
            }
        }
        byte[] disabledSurroundEncodings = getAudioEncodingsAsProto(disabledSurroundEncodingsList);
        byte[] enabledSurroundEncodings = getAudioEncodingsAsProto(enabledSurroundEncodingsList);
        byte[] disabledSurroundEncodings = toBytes(disabledSurroundEncodingsList);
        byte[] enabledSurroundEncodings = toBytes(enabledSurroundEncodingsList);
        int surroundOutputMode = audioManager.getEncodedSurroundMode();

        // TODO(b/203185126) : Remove the display capabilities metrics mock and retrieve actual
        //  metrics
        byte[] mockByteArray = new byte[0];
        DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
        Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
        // get the display capabilities metrics information
        Display.HdrCapabilities hdrCapabilities = display.getHdrCapabilities();
        byte[] sinkHdrFormats = new byte[]{};
        if (hdrCapabilities != null) {
            sinkHdrFormats = toBytes(hdrCapabilities.getSupportedHdrTypes());
        }
        byte[] sinkDisplayModes = toBytes(display.getSupportedModes());
        int hdcpLevel = -1;
        List<UUID> uuids = MediaDrm.getSupportedCryptoSchemes();
        try {
            if (!uuids.isEmpty()) {
                MediaDrm mediaDrm = new MediaDrm(uuids.get(0));
                hdcpLevel = mediaDrm.getConnectedHdcpLevel();
            }
        } catch (UnsupportedSchemeException exception) {
            Slog.e(TAG, "pulling hdcp level failed.", exception);
            hdcpLevel = -1;
        }

        // get the display settings metrics information
        int matchContentFrameRateUserPreference =
                displayManager.getMatchContentFrameRateUserPreference();
        byte[] userDisabledHdrTypes = toBytes(displayManager.getUserDisabledHdrTypes());
        Display.Mode userPreferredDisplayMode = displayManager.getUserPreferredDisplayMode();
        int userPreferredWidth = userPreferredDisplayMode != null
                ? userPreferredDisplayMode.getPhysicalWidth() : -1;
        int userPreferredHeight = userPreferredDisplayMode != null
                ? userPreferredDisplayMode.getPhysicalHeight() : -1;
        float userPreferredRefreshRate = userPreferredDisplayMode != null
                ? userPreferredDisplayMode.getRefreshRate() : 0.0f;
        boolean hasUserDisabledAllm = false;
        try {
            hasUserDisabledAllm = Settings.Secure.getIntForUser(
                    mContext.getContentResolver(),
                    Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED,
                    1) == 0;
        } catch (Settings.SettingNotFoundException exception) {
            Slog.e(
                    TAG, "unable to find setting for MINIMAL_POST_PROCESSING_ALLOWED.",
                    exception);
            hasUserDisabledAllm = false;
        }

        pulledData.add(
                FrameworkStatsLog.buildStatsEvent(
                        atomTag, surroundEncodings, sinkSurroundEncodings,
                        disabledSurroundEncodings, enabledSurroundEncodings, surroundOutputMode,
                        mockByteArray, mockByteArray, -1, -1, mockByteArray,
                        -1, -1, 0.0f, false));
                        sinkHdrFormats, sinkDisplayModes, hdcpLevel,
                        matchContentFrameRateUserPreference, userDisabledHdrTypes,
                        userPreferredWidth, userPreferredHeight, userPreferredRefreshRate,
                        hasUserDisabledAllm));

        return StatsManager.PULL_SUCCESS;
    }

    private byte[] getAudioEncodingsAsProto(List<Integer> audioEncodings) {
    private byte[] toBytes(List<Integer> audioEncodings) {
        ProtoOutputStream protoOutputStream = new ProtoOutputStream();
        for (int audioEncoding : audioEncodings) {
            protoOutputStream.write(
@@ -4532,6 +4578,72 @@ public class StatsPullAtomService extends SystemService {
        return protoOutputStream.getBytes();
    }

    private byte[] toBytes(int[] array) {
        ProtoOutputStream protoOutputStream = new ProtoOutputStream();
        for (int element : array) {
            protoOutputStream.write(
                    ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_ENUM | 1,
                    element);
        }
        return protoOutputStream.getBytes();
    }

    private byte[] toBytes(Display.Mode[] displayModes) {
        Map<Integer, Integer> modeGroupIds = createModeGroups(displayModes);
        ProtoOutputStream protoOutputStream = new ProtoOutputStream();
        for (Display.Mode element : displayModes) {
            ProtoOutputStream protoOutputStreamMode = new ProtoOutputStream();
            protoOutputStreamMode.write(
                    ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_INT32 | 1,
                    element.getPhysicalHeight());
            protoOutputStreamMode.write(
                    ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_INT32 | 2,
                    element.getPhysicalWidth());
            protoOutputStreamMode.write(
                    ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_FLOAT | 3,
                    element.getRefreshRate());
            protoOutputStreamMode.write(
                    ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_INT32 | 4,
                    modeGroupIds.get(element.getModeId()));
            protoOutputStream.write(
                    ProtoOutputStream.FIELD_COUNT_REPEATED
                            | ProtoOutputStream.FIELD_TYPE_MESSAGE | 1,
                    protoOutputStreamMode.getBytes());
        }
        return protoOutputStream.getBytes();
    }

    // Returns map modeId -> groupId such that all modes with the same group have alternative
    // refresh rates
    private Map<Integer, Integer> createModeGroups(Display.Mode[] supportedModes) {
        Map<Integer, Integer> modeGroupIds = new ArrayMap<>();
        int groupId = 1;
        for (Display.Mode mode : supportedModes) {
            if (modeGroupIds.containsKey(mode.getModeId())) {
                continue;
            }
            modeGroupIds.put(mode.getModeId(), groupId);
            for (float refreshRate : mode.getAlternativeRefreshRates()) {
                int alternativeModeId = findModeId(supportedModes, mode.getPhysicalWidth(),
                        mode.getPhysicalHeight(), refreshRate);
                if (alternativeModeId != -1 && !modeGroupIds.containsKey(alternativeModeId)) {
                    modeGroupIds.put(alternativeModeId, groupId);
                }
            }
            groupId++;
        }
        return modeGroupIds;
    }

    private int findModeId(Display.Mode[] modes, int width, int height, float refreshRate) {
        for (Display.Mode mode : modes) {
            if (mode.matches(width, height, refreshRate)) {
                return mode.getModeId();
            }
        }
        return -1;
    }

    /**
     * Counts how many accessibility services (including features) there are in the colon-separated
     * string list.