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

Commit 6d295775 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 9065525 from 9b24df2c to tm-qpr1-release

Change-Id: I97d0a9cf4c9477f39176e333d8f3325ddcf0e3e5
parents 4ce2dcc5 9b24df2c
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -1476,10 +1476,18 @@
    <string name="fingerprint_delete_message">Do you want to delete this fingerprint?</string>
    <!-- Message shown in a dialog which asks the user to confirm when a single fingerprint gets deleted. [CHAR LIMIT=NONE]-->
    <string name="fingerprint_v2_delete_message">This deletes the fingerprint images and model associated with \'<xliff:g id="fingerprint_id" example="Fingerprint 2">%1$s</xliff:g>\' that are stored on your device</string>
    <string name="fingerprint_v2_delete_message" product="default">This deletes the fingerprint images and model associated with \'<xliff:g id="fingerprint_id" example="Fingerprint 2">%1$s</xliff:g>\' that are stored on your phone</string>
    <!-- Message shown in a dialog which asks the user to confirm when a single fingerprint gets deleted. [CHAR LIMIT=NONE]-->
    <string name="fingerprint_v2_delete_message" product="tablet">This deletes the fingerprint images and model associated with \'<xliff:g id="fingerprint_id" example="Fingerprint 2">%1$s</xliff:g>\' that are stored on your tablet</string>
    <!-- Message shown in a dialog which asks the user to confirm when a single fingerprint gets deleted. [CHAR LIMIT=NONE]-->
    <string name="fingerprint_v2_delete_message" product="device">This deletes the fingerprint images and model associated with \'<xliff:g id="fingerprint_id" example="Fingerprint 2">%1$s</xliff:g>\' that are stored on your device</string>
    <!-- Message shown in a dialog which asks the user to confirm when the last fingerprint gets deleted by him. [CHAR LIMIT=NONE]-->
    <string name="fingerprint_last_delete_message">You won\'t be able to use your fingerprint to unlock your phone or verify it\'s you in apps.</string>
    <string name="fingerprint_last_delete_message" product="default">You won\'t be able to use your fingerprint to unlock your phone or verify it\'s you in apps.</string>
    <!-- Message shown in a dialog which asks the user to confirm when the last fingerprint gets deleted by him. [CHAR LIMIT=NONE]-->
    <string name="fingerprint_last_delete_message" product="tablet">You won\'t be able to use your fingerprint to unlock your tablet or verify it\'s you in apps.</string>
    <!-- Message shown in a dialog which asks the user to confirm when the last fingerprint gets deleted by him. [CHAR LIMIT=NONE]-->
    <string name="fingerprint_last_delete_message" product="device">You won\'t be able to use your fingerprint to unlock your device or verify it\'s you in apps.</string>
    <string name="fingerprint_last_delete_message_profile_challenge">You won\'t be able to use your fingerprint to unlock your work profile, authorize purchases, or sign in to work apps.</string>
    <!-- Button to confirm the last removing the last fingerprint. [CHAR LIMIT=20]-->
+64 −42
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.View;
import android.view.accessibility.AccessibilityManager;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -107,12 +108,9 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
    private boolean mIs24HourFormat;
    private boolean mIsFooterPrefAdded = false;
    private View mBatteryChartViewGroup;
    private View mCategoryTitleView;
    private PreferenceScreen mPreferenceScreen;
    private FooterPreference mFooterPreference;
    // Daily view model only saves abbreviated day of week texts (e.g. MON). This field saves the
    // full day of week texts (e.g. Monday), which is used in category title and battery detail
    // page.
    private List<String> mDailyTimestampFullTexts;
    private BatteryChartViewModel mDailyViewModel;
    private List<BatteryChartViewModel> mHourlyViewModels;

@@ -127,6 +125,13 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
    private final AnimatorListenerAdapter mHourlyChartFadeOutAdapter =
            createHourlyChartAnimatorListenerAdapter(/*isToShow=*/ false);

    @VisibleForTesting
    final DailyChartLabelTextGenerator mDailyChartLabelTextGenerator =
            new DailyChartLabelTextGenerator();
    @VisibleForTesting
    final HourlyChartLabelTextGenerator mHourlyChartLabelTextGenerator =
            new HourlyChartLabelTextGenerator();

    // Preference cache to avoid create new instance each time.
    @VisibleForTesting
    final Map<String, Preference> mPreferenceCache = new HashMap<>();
@@ -284,29 +289,24 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
                getTotalHours(batteryLevelData));

        if (batteryLevelData == null) {
            mDailyTimestampFullTexts = null;
            mDailyViewModel = null;
            mHourlyViewModels = null;
            refreshUi();
            return;
        }
        mDailyTimestampFullTexts = generateTimestampDayOfWeekTexts(
                mContext, batteryLevelData.getDailyBatteryLevels().getTimestamps(),
                /* isAbbreviation= */ false);
        mDailyViewModel = new BatteryChartViewModel(
                batteryLevelData.getDailyBatteryLevels().getLevels(),
                generateTimestampDayOfWeekTexts(
                        mContext, batteryLevelData.getDailyBatteryLevels().getTimestamps(),
                        /* isAbbreviation= */ true),
                BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS);
                batteryLevelData.getDailyBatteryLevels().getTimestamps(),
                BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS,
                mDailyChartLabelTextGenerator);
        mHourlyViewModels = new ArrayList<>();
        for (BatteryLevelData.PeriodBatteryLevelData hourlyBatteryLevelsPerDay :
                batteryLevelData.getHourlyBatteryLevelsPerDay()) {
            mHourlyViewModels.add(new BatteryChartViewModel(
                    hourlyBatteryLevelsPerDay.getLevels(),
                    generateTimestampHourTexts(
                            mContext, hourlyBatteryLevelsPerDay.getTimestamps()),
                    BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS));
                    hourlyBatteryLevelsPerDay.getTimestamps(),
                    BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS,
                    mHourlyChartLabelTextGenerator));
        }
        refreshUi();
    }
@@ -334,6 +334,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
            mDailyChartIndex = trapezoidIndex;
            mHourlyChartIndex = BatteryChartViewModel.SELECTED_INDEX_ALL;
            refreshUi();
            requestAccessibilityFocusForCategoryTitle(mDailyChartView);
            mMetricsFeatureProvider.action(
                    mPrefContext,
                    trapezoidIndex == BatteryChartViewModel.SELECTED_INDEX_ALL
@@ -349,6 +350,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
            Log.d(TAG, "onHourlyChartSelect:" + trapezoidIndex);
            mHourlyChartIndex = trapezoidIndex;
            refreshUi();
            requestAccessibilityFocusForCategoryTitle(mHourlyChartView);
            mMetricsFeatureProvider.action(
                    mPrefContext,
                    trapezoidIndex == BatteryChartViewModel.SELECTED_INDEX_ALL
@@ -532,6 +534,18 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
        }
    }

    private void requestAccessibilityFocusForCategoryTitle(View view) {
        if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
            return;
        }
        if (mCategoryTitleView == null) {
            mCategoryTitleView = view.getRootView().findViewById(com.android.internal.R.id.title);
        }
        if (mCategoryTitleView != null) {
            mCategoryTitleView.requestAccessibilityFocus();
        }
    }

    private String getSlotInformation(boolean isApp, String slotInformation) {
        // TODO: Updates the right slot information from daily and hourly chart selection.
        // Null means we show all information without a specific time slot.
@@ -548,8 +562,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll

    @VisibleForTesting
    String getSlotInformation() {
        if (mDailyTimestampFullTexts == null || mDailyViewModel == null
                || mHourlyViewModels == null) {
        if (mDailyViewModel == null || mHourlyViewModels == null) {
            // No data
            return null;
        }
@@ -557,17 +570,13 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
            return null;
        }

        final String selectedDayText = mDailyTimestampFullTexts.get(mDailyChartIndex);
        final String selectedDayText = mDailyViewModel.getFullText(mDailyChartIndex);
        if (mHourlyChartIndex == BatteryChartViewModel.SELECTED_INDEX_ALL) {
            return selectedDayText;
        }

        final String fromHourText = mHourlyViewModels.get(mDailyChartIndex).texts().get(
        final String selectedHourText = mHourlyViewModels.get(mDailyChartIndex).getFullText(
                mHourlyChartIndex);
        final String toHourText = mHourlyViewModels.get(mDailyChartIndex).texts().get(
                mHourlyChartIndex + 1);
        final String selectedHourText =
                String.format("%s%s%s", fromHourText, mIs24HourFormat ? "-" : " - ", toHourText);
        if (isBatteryLevelDataInOneDay()) {
            return selectedHourText;
        }
@@ -712,25 +721,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
                / DateUtils.HOUR_IN_MILLIS);
    }

    private static List<String> generateTimestampDayOfWeekTexts(@NonNull final Context context,
            @NonNull final List<Long> timestamps, final boolean isAbbreviation) {
        final ArrayList<String> texts = new ArrayList<>();
        for (Long timestamp : timestamps) {
            texts.add(ConvertUtils.utcToLocalTimeDayOfWeek(context, timestamp, isAbbreviation));
        }
        return texts;
    }

    private static List<String> generateTimestampHourTexts(
            @NonNull final Context context, @NonNull final List<Long> timestamps) {
        final boolean is24HourFormat = DateFormat.is24HourFormat(context);
        final ArrayList<String> texts = new ArrayList<>();
        for (Long timestamp : timestamps) {
            texts.add(ConvertUtils.utcToLocalTimeHour(context, timestamp, is24HourFormat));
        }
        return texts;
    }

    /** Used for {@link AppBatteryPreferenceController}. */
    public static List<BatteryDiffEntry> getAppBatteryUsageData(Context context) {
        final long start = System.currentTimeMillis();
@@ -776,4 +766,36 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
        }
        return null;
    }

    private final class DailyChartLabelTextGenerator implements
            BatteryChartViewModel.LabelTextGenerator {
        @Override
        public String generateText(List<Long> timestamps, int index) {
            return ConvertUtils.utcToLocalTimeDayOfWeek(mContext,
                    timestamps.get(index), /* isAbbreviation= */ true);
        }

        @Override
        public String generateFullText(List<Long> timestamps, int index) {
            return ConvertUtils.utcToLocalTimeDayOfWeek(mContext,
                    timestamps.get(index), /* isAbbreviation= */ false);
        }
    }

    private final class HourlyChartLabelTextGenerator implements
            BatteryChartViewModel.LabelTextGenerator {
        @Override
        public String generateText(List<Long> timestamps, int index) {
            return ConvertUtils.utcToLocalTimeHour(mContext, timestamps.get(index),
                    mIs24HourFormat);
        }

        @Override
        public String generateFullText(List<Long> timestamps, int index) {
            return index == timestamps.size() - 1
                    ? generateText(timestamps, index)
                    : String.format("%s%s%s", generateText(timestamps, index),
                            mIs24HourFormat ? "-" : " - ", generateText(timestamps, index + 1));
        }
    }
}
+130 −144

File changed.

Preview size limit exceeded, changes collapsed.

+54 −18
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.settings.fuelgauge.batteryusage;
import androidx.annotation.NonNull;
import androidx.core.util.Preconditions;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@@ -38,34 +39,59 @@ class BatteryChartViewModel {
        CENTER_OF_TRAPEZOIDS,
    }

    interface LabelTextGenerator {
        /** Generate the label text. The text may be abbreviated to save space. */
        String generateText(List<Long> timestamps, int index);

        /** Generate the full text for accessibility. */
        String generateFullText(List<Long> timestamps, int index);
    }

    private final List<Integer> mLevels;
    private final List<String> mTexts;
    private final List<Long> mTimestamps;
    private final AxisLabelPosition mAxisLabelPosition;
    private final LabelTextGenerator mLabelTextGenerator;
    private final String[] mTexts;
    private final String[] mFullTexts;

    private int mSelectedIndex = SELECTED_INDEX_ALL;

    BatteryChartViewModel(
            @NonNull List<Integer> levels, @NonNull List<String> texts,
            @NonNull AxisLabelPosition axisLabelPosition) {
    BatteryChartViewModel(@NonNull List<Integer> levels, @NonNull List<Long> timestamps,
            @NonNull AxisLabelPosition axisLabelPosition,
            @NonNull LabelTextGenerator labelTextGenerator) {
        Preconditions.checkArgument(
                levels.size() == texts.size() && levels.size() >= MIN_LEVELS_DATA_SIZE,
                levels.size() == timestamps.size() && levels.size() >= MIN_LEVELS_DATA_SIZE,
                String.format(Locale.ENGLISH,
                        "Invalid BatteryChartViewModel levels.size: %d, texts.size: %d.",
                        levels.size(), texts.size()));
                        "Invalid BatteryChartViewModel levels.size: %d, timestamps.size: %d.",
                        levels.size(), timestamps.size()));
        mLevels = levels;
        mTexts = texts;
        mTimestamps = timestamps;
        mAxisLabelPosition = axisLabelPosition;
        mLabelTextGenerator = labelTextGenerator;
        mTexts = new String[size()];
        mFullTexts = new String[size()];
    }

    public int size() {
        return mLevels.size();
    }

    public List<Integer> levels() {
        return mLevels;
    public Integer getLevel(int index) {
        return mLevels.get(index);
    }

    public String getText(int index) {
        if (mTexts[index] == null) {
            mTexts[index] = mLabelTextGenerator.generateText(mTimestamps, index);
        }
        return mTexts[index];
    }

    public List<String> texts() {
        return mTexts;
    public String getFullText(int index) {
        if (mFullTexts[index] == null) {
            mFullTexts[index] = mLabelTextGenerator.generateFullText(mTimestamps, index);
        }
        return mFullTexts[index];
    }

    public AxisLabelPosition axisLabelPosition() {
@@ -82,7 +108,7 @@ class BatteryChartViewModel {

    @Override
    public int hashCode() {
        return Objects.hash(mLevels, mTexts, mSelectedIndex, mAxisLabelPosition);
        return Objects.hash(mLevels, mTimestamps, mSelectedIndex, mAxisLabelPosition);
    }

    @Override
@@ -94,16 +120,26 @@ class BatteryChartViewModel {
        }
        final BatteryChartViewModel batteryChartViewModel = (BatteryChartViewModel) other;
        return Objects.equals(mLevels, batteryChartViewModel.mLevels)
                && Objects.equals(mTexts, batteryChartViewModel.mTexts)
                && Objects.equals(mTimestamps, batteryChartViewModel.mTimestamps)
                && mAxisLabelPosition == batteryChartViewModel.mAxisLabelPosition
                && mSelectedIndex == batteryChartViewModel.mSelectedIndex;
    }

    @Override
    public String toString() {
        return String.format(Locale.ENGLISH,
                "levels: %s,\ntexts: %s,\naxisLabelPosition: %s, selectedIndex: %d",
                Objects.toString(mLevels), Objects.toString(mTexts), mAxisLabelPosition,
                mSelectedIndex);
        // Generate all the texts and full texts.
        for (int i = 0; i < size(); i++) {
            getText(i);
            getFullText(i);
        }

        return new StringBuilder()
                .append("levels: " + Objects.toString(mLevels))
                .append(", timestamps: " + Objects.toString(mTimestamps))
                .append(", texts: " + Arrays.toString(mTexts))
                .append(", fullTexts: " + Arrays.toString(mFullTexts))
                .append(", axisLabelPosition: " + mAxisLabelPosition)
                .append(", selectedIndex: " + mSelectedIndex)
                .toString();
    }
}
+26 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.settings.fuelgauge.batteryusage;

import static com.android.settings.fuelgauge.batteryusage.ConvertUtils.utcToLocalTime;

import android.app.settings.SettingsEnums;
import android.content.ContentValues;
import android.content.Context;
import android.os.AsyncTask;
@@ -36,6 +37,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.Utils;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.fuelgauge.BatteryStatus;

import java.time.Duration;
@@ -354,10 +356,25 @@ public final class DataProcessor {
        insertDailyUsageDiffData(hourlyBatteryLevelsPerDay, resultMap);
        // Insert diff data [SELECTED_INDEX_ALL][SELECTED_INDEX_ALL].
        insertAllUsageDiffData(resultMap);
        // Compute the apps number before purge. Must put before purgeLowPercentageAndFakeData.
        final int countOfAppBeforePurge = getCountOfApps(resultMap);
        purgeLowPercentageAndFakeData(context, resultMap);
        // Compute the apps number after purge. Must put after purgeLowPercentageAndFakeData.
        final int countOfAppAfterPurge = getCountOfApps(resultMap);
        if (!isUsageMapValid(resultMap, hourlyBatteryLevelsPerDay)) {
            return null;
        }

        final MetricsFeatureProvider metricsFeatureProvider =
                FeatureFactory.getFactory(context).getMetricsFeatureProvider();
        metricsFeatureProvider.action(
                context,
                SettingsEnums.ACTION_BATTERY_USAGE_SHOWN_APP_COUNT,
                countOfAppAfterPurge);
        metricsFeatureProvider.action(
                context,
                SettingsEnums.ACTION_BATTERY_USAGE_HIDDEN_APP_COUNT,
                countOfAppBeforePurge - countOfAppAfterPurge);
        return resultMap;
    }

@@ -933,6 +950,15 @@ public final class DataProcessor {
        return calendar.getTimeInMillis();
    }

    private static int getCountOfApps(final Map<Integer, Map<Integer, BatteryDiffData>> resultMap) {
        final BatteryDiffData diffDataList =
                resultMap.get(SELECTED_INDEX_ALL).get(SELECTED_INDEX_ALL);
        return diffDataList == null
                ? 0
                : diffDataList.getAppDiffEntryList().size()
                        + diffDataList.getSystemDiffEntryList().size();
    }

    private static boolean contains(String target, Set<CharSequence> packageNames) {
        if (target != null && packageNames != null) {
            for (CharSequence packageName : packageNames) {
Loading