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

Commit 62a011d2 authored by Neil Fuller's avatar Neil Fuller
Browse files

Refactoring: Move code to StatsPullAtomService

Refactoring: Move time zone detection metrics byte[] generation code to
StatsPullAtomService so it's clearer what information is sent off of the
device. Previously, the byte[] was generated in service code
(MetricsTimeZoneDetectorState), which means that changes don't require
metrics team OWNERS approval and changes could be missed.

This change is a refactoring before an upcoming addition to the byte[]
content is actually made.

Bug: 200279201
Test: build only
Change-Id: I79a03580b204b78cfb9f969f460d1fd8475befdb
parent f4c16dc4
Loading
Loading
Loading
Loading
+39 −4
Original line number Original line Diff line number Diff line
@@ -64,6 +64,8 @@ import static com.android.server.stats.pull.ProcfsMemoryUtil.getProcessCmdlines;
import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs;
import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs;
import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;


import static libcore.io.IoUtils.closeQuietly;

import static java.lang.Math.min;
import static java.lang.Math.min;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MICROSECONDS;
import static java.util.concurrent.TimeUnit.MICROSECONDS;
@@ -222,6 +224,7 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONObject;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.IOException;
@@ -3413,9 +3416,12 @@ public class StatsPullAtomService extends SystemService {
                    metricsState.getGeoDetectionEnabledSetting(),
                    metricsState.getGeoDetectionEnabledSetting(),
                    convertToMetricsDetectionMode(metricsState.getDetectionMode()),
                    convertToMetricsDetectionMode(metricsState.getDetectionMode()),
                    metricsState.getDeviceTimeZoneIdOrdinal(),
                    metricsState.getDeviceTimeZoneIdOrdinal(),
                    metricsState.getLatestManualSuggestionProtoBytes(),
                    convertTimeZoneSuggestionToProtoBytes(
                    metricsState.getLatestTelephonySuggestionProtoBytes(),
                            metricsState.getLatestManualSuggestion()),
                    metricsState.getLatestGeolocationSuggestionProtoBytes()
                    convertTimeZoneSuggestionToProtoBytes(
                            metricsState.getLatestTelephonySuggestion()),
                    convertTimeZoneSuggestionToProtoBytes(
                            metricsState.getLatestGeolocationSuggestion())
            ));
            ));
        } catch (RuntimeException e) {
        } catch (RuntimeException e) {
            Slog.e(TAG, "Getting time zone detection state failed: ", e);
            Slog.e(TAG, "Getting time zone detection state failed: ", e);
@@ -3426,7 +3432,8 @@ public class StatsPullAtomService extends SystemService {
        return StatsManager.PULL_SUCCESS;
        return StatsManager.PULL_SUCCESS;
    }
    }


    private int convertToMetricsDetectionMode(int detectionMode) {
    private static int convertToMetricsDetectionMode(
            @MetricsTimeZoneDetectorState.DetectionMode int detectionMode) {
        switch (detectionMode) {
        switch (detectionMode) {
            case MetricsTimeZoneDetectorState.DETECTION_MODE_MANUAL:
            case MetricsTimeZoneDetectorState.DETECTION_MODE_MANUAL:
                return TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__MANUAL;
                return TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__MANUAL;
@@ -3439,6 +3446,34 @@ public class StatsPullAtomService extends SystemService {
        }
        }
    }
    }


    @Nullable
    private static byte[] convertTimeZoneSuggestionToProtoBytes(
            @Nullable MetricsTimeZoneDetectorState.MetricsTimeZoneSuggestion suggestion) {
        if (suggestion == null) {
            return null;
        }

        // We don't get access to the atoms.proto definition for nested proto fields, so we use
        // an identically specified proto.
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ProtoOutputStream protoOutputStream = new ProtoOutputStream(byteArrayOutputStream);
        int typeProtoValue = suggestion.isCertain()
                ? android.app.time.MetricsTimeZoneSuggestion.CERTAIN
                : android.app.time.MetricsTimeZoneSuggestion.UNCERTAIN;
        protoOutputStream.write(android.app.time.MetricsTimeZoneSuggestion.TYPE,
                typeProtoValue);
        if (suggestion.isCertain()) {
            for (int zoneIdOrdinal : suggestion.getZoneIdOrdinals()) {
                protoOutputStream.write(
                        android.app.time.MetricsTimeZoneSuggestion.TIME_ZONE_ORDINALS,
                        zoneIdOrdinal);
            }
        }
        protoOutputStream.flush();
        closeQuietly(byteArrayOutputStream);
        return byteArrayOutputStream.toByteArray();
    }

    private void registerExternalStorageInfo() {
    private void registerExternalStorageInfo() {
        int tagId = FrameworkStatsLog.EXTERNAL_STORAGE_INFO;
        int tagId = FrameworkStatsLog.EXTERNAL_STORAGE_INFO;
        mStatsManager.setPullAtomCallback(
        mStatsManager.setPullAtomCallback(
+22 −58
Original line number Original line Diff line number Diff line
@@ -16,16 +16,12 @@


package com.android.server.timezonedetector;
package com.android.server.timezonedetector;


import static libcore.io.IoUtils.closeQuietly;

import android.annotation.IntDef;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
import android.util.proto.ProtoOutputStream;


import java.io.ByteArrayOutputStream;
import java.lang.annotation.ElementType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
@@ -50,7 +46,7 @@ public final class MetricsTimeZoneDetectorState {
            value = { DETECTION_MODE_MANUAL, DETECTION_MODE_GEO, DETECTION_MODE_TELEPHONY})
            value = { DETECTION_MODE_MANUAL, DETECTION_MODE_GEO, DETECTION_MODE_TELEPHONY})
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
    @Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER })
    @Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER })
    @interface DetectionMode {};
    public @interface DetectionMode {};


    public static final @DetectionMode int DETECTION_MODE_MANUAL = 0;
    public static final @DetectionMode int DETECTION_MODE_MANUAL = 0;
    public static final @DetectionMode int DETECTION_MODE_GEO = 1;
    public static final @DetectionMode int DETECTION_MODE_GEO = 1;
@@ -89,16 +85,16 @@ public final class MetricsTimeZoneDetectorState {


        int deviceTimeZoneIdOrdinal =
        int deviceTimeZoneIdOrdinal =
                tzIdOrdinalGenerator.ordinal(Objects.requireNonNull(deviceTimeZoneId));
                tzIdOrdinalGenerator.ordinal(Objects.requireNonNull(deviceTimeZoneId));
        MetricsTimeZoneSuggestion latestObfuscatedManualSuggestion =
        MetricsTimeZoneSuggestion latestCanonicalManualSuggestion =
                createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestManualSuggestion);
                createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestManualSuggestion);
        MetricsTimeZoneSuggestion latestObfuscatedTelephonySuggestion =
        MetricsTimeZoneSuggestion latestCanonicalTelephonySuggestion =
                createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestTelephonySuggestion);
                createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestTelephonySuggestion);
        MetricsTimeZoneSuggestion latestObfuscatedGeolocationSuggestion =
        MetricsTimeZoneSuggestion latestCanonicalGeolocationSuggestion =
                createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestGeolocationSuggestion);
                createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestGeolocationSuggestion);


        return new MetricsTimeZoneDetectorState(
        return new MetricsTimeZoneDetectorState(
                configurationInternal, deviceTimeZoneIdOrdinal, latestObfuscatedManualSuggestion,
                configurationInternal, deviceTimeZoneIdOrdinal, latestCanonicalManualSuggestion,
                latestObfuscatedTelephonySuggestion, latestObfuscatedGeolocationSuggestion);
                latestCanonicalTelephonySuggestion, latestCanonicalGeolocationSuggestion);
    }
    }


    /** Returns true if the device supports telephony time zone detection. */
    /** Returns true if the device supports telephony time zone detection. */
@@ -154,30 +150,27 @@ public final class MetricsTimeZoneDetectorState {
    }
    }


    /**
    /**
     * Returns bytes[] for a {@link MetricsTimeZoneSuggestion} for the last manual
     * Returns a canonical form of the last manual suggestion received.
     * suggestion received.
     */
     */
    @Nullable
    @Nullable
    public byte[] getLatestManualSuggestionProtoBytes() {
    public MetricsTimeZoneSuggestion getLatestManualSuggestion() {
        return suggestionProtoBytes(mLatestManualSuggestion);
        return mLatestManualSuggestion;
    }
    }


    /**
    /**
     * Returns bytes[] for a {@link MetricsTimeZoneSuggestion} for the last, best
     * Returns a canonical form of the last telephony suggestion received.
     * telephony suggestion received.
     */
     */
    @Nullable
    @Nullable
    public byte[] getLatestTelephonySuggestionProtoBytes() {
    public MetricsTimeZoneSuggestion getLatestTelephonySuggestion() {
        return suggestionProtoBytes(mLatestTelephonySuggestion);
        return mLatestTelephonySuggestion;
    }
    }


    /**
    /**
     * Returns bytes[] for a {@link MetricsTimeZoneSuggestion} for the last geolocation
     * Returns a canonical form of last geolocation suggestion received.
     * suggestion received.
     */
     */
    @Nullable
    @Nullable
    public byte[] getLatestGeolocationSuggestionProtoBytes() {
    public MetricsTimeZoneSuggestion getLatestGeolocationSuggestion() {
        return suggestionProtoBytes(mLatestGeolocationSuggestion);
        return mLatestGeolocationSuggestion;
    }
    }


    @Override
    @Override
@@ -213,14 +206,6 @@ public final class MetricsTimeZoneDetectorState {
                + '}';
                + '}';
    }
    }


    private static byte[] suggestionProtoBytes(
            @Nullable MetricsTimeZoneSuggestion suggestion) {
        if (suggestion == null) {
            return null;
        }
        return suggestion.toBytes();
    }

    @Nullable
    @Nullable
    private static MetricsTimeZoneSuggestion createMetricsTimeZoneSuggestion(
    private static MetricsTimeZoneSuggestion createMetricsTimeZoneSuggestion(
            @NonNull OrdinalGenerator<String> zoneIdOrdinalGenerator,
            @NonNull OrdinalGenerator<String> zoneIdOrdinalGenerator,
@@ -264,10 +249,11 @@ public final class MetricsTimeZoneDetectorState {
    }
    }


    /**
    /**
     * A Java class that closely matches the android.app.time.MetricsTimeZoneSuggestion
     * A Java class that represents a generic time zone suggestion, i.e. one that is independent of
     * proto definition.
     * origin-specific information. This closely matches the metrics atoms.proto
     * MetricsTimeZoneSuggestion proto definition.
     */
     */
    private static final class MetricsTimeZoneSuggestion {
    public static final class MetricsTimeZoneSuggestion {
        @Nullable
        @Nullable
        private final int[] mZoneIdOrdinals;
        private final int[] mZoneIdOrdinals;


@@ -281,42 +267,20 @@ public final class MetricsTimeZoneDetectorState {
        }
        }


        @NonNull
        @NonNull
        public static MetricsTimeZoneSuggestion createCertain(
        static MetricsTimeZoneSuggestion createCertain(
                @NonNull int[] zoneIdOrdinals) {
                @NonNull int[] zoneIdOrdinals) {
            return new MetricsTimeZoneSuggestion(zoneIdOrdinals);
            return new MetricsTimeZoneSuggestion(zoneIdOrdinals);
        }
        }


        boolean isCertain() {
        public boolean isCertain() {
            return mZoneIdOrdinals != null;
            return mZoneIdOrdinals != null;
        }
        }


        @Nullable
        @Nullable
        int[] getZoneIdOrdinals() {
        public int[] getZoneIdOrdinals() {
            return mZoneIdOrdinals;
            return mZoneIdOrdinals;
        }
        }


        byte[] toBytes() {
            // We don't get access to the atoms.proto definition for nested proto fields, so we use
            // an identically specified proto.
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ProtoOutputStream protoOutputStream = new ProtoOutputStream(byteArrayOutputStream);
            int typeProtoValue = isCertain()
                    ? android.app.time.MetricsTimeZoneSuggestion.CERTAIN
                    : android.app.time.MetricsTimeZoneSuggestion.UNCERTAIN;
            protoOutputStream.write(android.app.time.MetricsTimeZoneSuggestion.TYPE,
                    typeProtoValue);
            if (isCertain()) {
                for (int zoneIdOrdinal : getZoneIdOrdinals()) {
                    protoOutputStream.write(
                            android.app.time.MetricsTimeZoneSuggestion.TIME_ZONE_ORDINALS,
                            zoneIdOrdinal);
                }
            }
            protoOutputStream.flush();
            closeQuietly(byteArrayOutputStream);
            return byteArrayOutputStream.toByteArray();
        }

        @Override
        @Override
        public boolean equals(Object o) {
        public boolean equals(Object o) {
            if (this == o) {
            if (this == o) {