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

Commit ecabb7d6 authored by Angela Wang's avatar Angela Wang Committed by Android (Google) Code Review
Browse files

Merge "Use date difference to remove the expired data" into main

parents 0f77e071 d5333f28
Loading
Loading
Loading
Loading
+24 −22
Original line number Original line Diff line number Diff line
@@ -19,8 +19,6 @@ package com.android.settingslib.bluetooth;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences;
import android.icu.text.SimpleDateFormat;
import android.icu.util.TimeZone;
import android.util.Log;
import android.util.Log;


import androidx.annotation.IntDef;
import androidx.annotation.IntDef;
@@ -31,12 +29,14 @@ import com.android.internal.util.FrameworkStatsLog;


import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Set;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Collectors;


/** Utils class to report hearing aid metrics to statsd */
/** Utils class to report hearing aid metrics to statsd */
@@ -55,13 +55,13 @@ public final class HearingAidStatsLogUtils {
    private static final String BT_HEARING_USER_CATEGORY = "bt_hearing_user_category";
    private static final String BT_HEARING_USER_CATEGORY = "bt_hearing_user_category";


    private static final String HISTORY_RECORD_DELIMITER = ",";
    private static final String HISTORY_RECORD_DELIMITER = ",";
    private static final String CATEGORY_HEARING_AIDS = "A11yHearingAidsUser";
    static final String CATEGORY_HEARING_AIDS = "A11yHearingAidsUser";
    private static final String CATEGORY_NEW_HEARING_AIDS = "A11yNewHearingAidsUser";
    static final String CATEGORY_NEW_HEARING_AIDS = "A11yNewHearingAidsUser";
    private static final String CATEGORY_HEARING_DEVICES = "A11yHearingDevicesUser";
    static final String CATEGORY_HEARING_DEVICES = "A11yHearingDevicesUser";
    private static final String CATEGORY_NEW_HEARING_DEVICES = "A11yNewHearingDevicesUser";
    static final String CATEGORY_NEW_HEARING_DEVICES = "A11yNewHearingDevicesUser";


    private static final long PAIRED_HISTORY_EXPIRED_TIME = TimeUnit.DAYS.toMillis(30);
    static final int PAIRED_HISTORY_EXPIRED_DAY = 30;
    private static final long CONNECTED_HISTORY_EXPIRED_TIME = TimeUnit.DAYS.toMillis(7);
    static final int CONNECTED_HISTORY_EXPIRED_DAY = 7;
    private static final int VALID_PAIRED_EVENT_COUNT = 1;
    private static final int VALID_PAIRED_EVENT_COUNT = 1;
    private static final int VALID_CONNECTED_EVENT_COUNT = 7;
    private static final int VALID_CONNECTED_EVENT_COUNT = 7;


@@ -263,7 +263,7 @@ public final class HearingAidStatsLogUtils {
            }
            }
            return;
            return;
        }
        }
        if (history.peekLast() != null && isSameDay(history.peekLast(), timestamp)) {
        if (history.peekLast() != null && isSameDay(timestamp, history.peekLast())) {
            if (DEBUG) {
            if (DEBUG) {
                Log.w(TAG, "Skip this record, it's same day record");
                Log.w(TAG, "Skip this record, it's same day record");
            }
            }
@@ -282,25 +282,25 @@ public final class HearingAidStatsLogUtils {
                || BT_HEARING_DEVICES_PAIRED_HISTORY.equals(spName)) {
                || BT_HEARING_DEVICES_PAIRED_HISTORY.equals(spName)) {
            LinkedList<Long> history = convertToHistoryList(
            LinkedList<Long> history = convertToHistoryList(
                    getSharedPreferences(context).getString(spName, ""));
                    getSharedPreferences(context).getString(spName, ""));
            removeRecordsBeforeTime(history, PAIRED_HISTORY_EXPIRED_TIME);
            removeRecordsBeforeDay(history, PAIRED_HISTORY_EXPIRED_DAY);
            return history;
            return history;
        } else if (BT_HEARING_AIDS_CONNECTED_HISTORY.equals(spName)
        } else if (BT_HEARING_AIDS_CONNECTED_HISTORY.equals(spName)
                || BT_HEARING_DEVICES_CONNECTED_HISTORY.equals(spName)) {
                || BT_HEARING_DEVICES_CONNECTED_HISTORY.equals(spName)) {
            LinkedList<Long> history = convertToHistoryList(
            LinkedList<Long> history = convertToHistoryList(
                    getSharedPreferences(context).getString(spName, ""));
                    getSharedPreferences(context).getString(spName, ""));
            removeRecordsBeforeTime(history, CONNECTED_HISTORY_EXPIRED_TIME);
            removeRecordsBeforeDay(history, CONNECTED_HISTORY_EXPIRED_DAY);
            return history;
            return history;
        }
        }
        return null;
        return null;
    }
    }


    private static void removeRecordsBeforeTime(LinkedList<Long> history, long time) {
    private static void removeRecordsBeforeDay(LinkedList<Long> history, int day) {
        if (history == null) {
        if (history == null || history.isEmpty()) {
            return;
            return;
        }
        }
        Long currentTime = System.currentTimeMillis();
        long currentTime = System.currentTimeMillis();
        while (history.peekFirst() != null
        while (history.peekFirst() != null
                && currentTime - history.peekFirst() > time) {
                && dayDifference(currentTime, history.peekFirst()) >= day) {
            history.poll();
            history.poll();
        }
        }
    }
    }
@@ -331,11 +331,13 @@ public final class HearingAidStatsLogUtils {
     * @return {@code true} if two timestamps are on the same day
     * @return {@code true} if two timestamps are on the same day
     */
     */
    private static boolean isSameDay(long t1, long t2) {
    private static boolean isSameDay(long t1, long t2) {
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
        return dayDifference(t1, t2) == 0;
        sdf.setTimeZone(TimeZone.getDefault());
    }
        String dateString1 = sdf.format(t1);
    private static long dayDifference(long t1, long t2) {
        String dateString2 = sdf.format(t2);
        ZoneId zoneId = ZoneId.systemDefault();
        return dateString1.equals(dateString2);
        LocalDate date1 = Instant.ofEpochMilli(t1).atZone(zoneId).toLocalDate();
        LocalDate date2 = Instant.ofEpochMilli(t2).atZone(zoneId).toLocalDate();
        return Math.abs(ChronoUnit.DAYS.between(date1, date2));
    }
    }


    private static SharedPreferences getSharedPreferences(Context context) {
    private static SharedPreferences getSharedPreferences(Context context) {
+80 −8
Original line number Original line Diff line number Diff line
@@ -16,6 +16,9 @@


package com.android.settingslib.bluetooth;
package com.android.settingslib.bluetooth;


import static com.android.settingslib.bluetooth.HearingAidStatsLogUtils.CONNECTED_HISTORY_EXPIRED_DAY;
import static com.android.settingslib.bluetooth.HearingAidStatsLogUtils.PAIRED_HISTORY_EXPIRED_DAY;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertThat;


import static org.mockito.Mockito.when;
import static org.mockito.Mockito.when;
@@ -34,6 +37,9 @@ import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RobolectricTestRunner;


import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeUnit;
@@ -84,8 +90,8 @@ public class HearingAidStatsLogUtilsTest {


    @Test
    @Test
    public void addCurrentTimeToHistory_addNewData() {
    public void addCurrentTimeToHistory_addNewData() {
        final long currentTime = System.currentTimeMillis();
        final long todayStartOfDay = convertToStartOfDayTime(System.currentTimeMillis());
        final long lastData = currentTime - TimeUnit.DAYS.toMillis(2);
        final long lastData = todayStartOfDay - TimeUnit.DAYS.toMillis(6);
        HearingAidStatsLogUtils.addToHistory(mContext, TEST_HISTORY_TYPE, lastData);
        HearingAidStatsLogUtils.addToHistory(mContext, TEST_HISTORY_TYPE, lastData);


        HearingAidStatsLogUtils.addCurrentTimeToHistory(mContext, TEST_HISTORY_TYPE);
        HearingAidStatsLogUtils.addCurrentTimeToHistory(mContext, TEST_HISTORY_TYPE);
@@ -96,22 +102,21 @@ public class HearingAidStatsLogUtilsTest {
    }
    }
    @Test
    @Test
    public void addCurrentTimeToHistory_skipSameDateData() {
    public void addCurrentTimeToHistory_skipSameDateData() {
        final long currentTime = System.currentTimeMillis();
        final long todayStartOfDay = convertToStartOfDayTime(System.currentTimeMillis());
        final long lastData = currentTime - 1;
        HearingAidStatsLogUtils.addToHistory(mContext, TEST_HISTORY_TYPE, todayStartOfDay);
        HearingAidStatsLogUtils.addToHistory(mContext, TEST_HISTORY_TYPE, lastData);


        HearingAidStatsLogUtils.addCurrentTimeToHistory(mContext, TEST_HISTORY_TYPE);
        HearingAidStatsLogUtils.addCurrentTimeToHistory(mContext, TEST_HISTORY_TYPE);


        LinkedList<Long> history = HearingAidStatsLogUtils.getHistory(mContext, TEST_HISTORY_TYPE);
        LinkedList<Long> history = HearingAidStatsLogUtils.getHistory(mContext, TEST_HISTORY_TYPE);
        assertThat(history).isNotNull();
        assertThat(history).isNotNull();
        assertThat(history.size()).isEqualTo(1);
        assertThat(history.size()).isEqualTo(1);
        assertThat(history.getFirst()).isEqualTo(lastData);
        assertThat(history.getFirst()).isEqualTo(todayStartOfDay);
    }
    }


    @Test
    @Test
    public void addCurrentTimeToHistory_cleanUpExpiredData() {
    public void addCurrentTimeToHistory_cleanUpExpiredData() {
        final long currentTime = System.currentTimeMillis();
        final long todayStartOfDay = convertToStartOfDayTime(System.currentTimeMillis());
        final long expiredData = currentTime - TimeUnit.DAYS.toMillis(10);
        final long expiredData = todayStartOfDay - TimeUnit.DAYS.toMillis(6) - 1;
        HearingAidStatsLogUtils.addToHistory(mContext, TEST_HISTORY_TYPE, expiredData);
        HearingAidStatsLogUtils.addToHistory(mContext, TEST_HISTORY_TYPE, expiredData);


        HearingAidStatsLogUtils.addCurrentTimeToHistory(mContext, TEST_HISTORY_TYPE);
        HearingAidStatsLogUtils.addCurrentTimeToHistory(mContext, TEST_HISTORY_TYPE);
@@ -121,4 +126,71 @@ public class HearingAidStatsLogUtilsTest {
        assertThat(history.size()).isEqualTo(1);
        assertThat(history.size()).isEqualTo(1);
        assertThat(history.getFirst()).isNotEqualTo(expiredData);
        assertThat(history.getFirst()).isNotEqualTo(expiredData);
    }
    }

    @Test
    public void getUserCategory_hearingAidsUser() {
        prepareHearingAidsUserHistory();

        assertThat(HearingAidStatsLogUtils.getUserCategory(mContext)).isEqualTo(
                HearingAidStatsLogUtils.CATEGORY_HEARING_AIDS);
    }

    @Test
    public void getUserCategory_newHearingAidsUser() {
        prepareHearingAidsUserHistory();
        prepareNewUserHistory();

        assertThat(HearingAidStatsLogUtils.getUserCategory(mContext)).isEqualTo(
                HearingAidStatsLogUtils.CATEGORY_NEW_HEARING_AIDS);
    }

    @Test
    public void getUserCategory_hearingDevicesUser() {
        prepareHearingDevicesUserHistory();

        assertThat(HearingAidStatsLogUtils.getUserCategory(mContext)).isEqualTo(
                HearingAidStatsLogUtils.CATEGORY_HEARING_DEVICES);
    }

    @Test
    public void getUserCategory_newHearingDevicesUser() {
        prepareHearingDevicesUserHistory();
        prepareNewUserHistory();

        assertThat(HearingAidStatsLogUtils.getUserCategory(mContext)).isEqualTo(
                HearingAidStatsLogUtils.CATEGORY_NEW_HEARING_DEVICES);
    }

    private long convertToStartOfDayTime(long timestamp) {
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDate date = Instant.ofEpochMilli(timestamp).atZone(zoneId).toLocalDate();
        return date.atStartOfDay(zoneId).toInstant().toEpochMilli();
    }

    private void prepareHearingAidsUserHistory() {
        final long todayStartOfDay = convertToStartOfDayTime(System.currentTimeMillis());
        for (int i = CONNECTED_HISTORY_EXPIRED_DAY - 1; i >= 0; i--) {
            final long data = todayStartOfDay - TimeUnit.DAYS.toMillis(i);
            HearingAidStatsLogUtils.addToHistory(mContext,
                    HearingAidStatsLogUtils.HistoryType.TYPE_HEARING_AIDS_CONNECTED, data);
        }
    }

    private void prepareHearingDevicesUserHistory() {
        final long todayStartOfDay = convertToStartOfDayTime(System.currentTimeMillis());
        for (int i = CONNECTED_HISTORY_EXPIRED_DAY - 1; i >= 0; i--) {
            final long data = todayStartOfDay - TimeUnit.DAYS.toMillis(i);
            HearingAidStatsLogUtils.addToHistory(mContext,
                    HearingAidStatsLogUtils.HistoryType.TYPE_HEARING_DEVICES_CONNECTED, data);
        }
    }

    private void prepareNewUserHistory() {
        final long todayStartOfDay = convertToStartOfDayTime(System.currentTimeMillis());
        final long data = todayStartOfDay - TimeUnit.DAYS.toMillis(PAIRED_HISTORY_EXPIRED_DAY - 1);
        HearingAidStatsLogUtils.addToHistory(mContext,
                HearingAidStatsLogUtils.HistoryType.TYPE_HEARING_AIDS_PAIRED, data);
        HearingAidStatsLogUtils.addToHistory(mContext,
                HearingAidStatsLogUtils.HistoryType.TYPE_HEARING_DEVICES_PAIRED, data);
    }
}
}