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

Commit 9555c952 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add shared strings to settingsLib"

parents 0ac01dd4 eb9ab29e
Loading
Loading
Loading
Loading
+39 −20
Original line number Original line Diff line number Diff line
@@ -866,29 +866,48 @@
    <string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>
    <string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>


  <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery discharging -->
  <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery discharging -->
    <string name="power_remaining_duration_only">About <xliff:g id="time">^1</xliff:g> left</string>
  <string name="power_remaining_duration_only">About <xliff:g id="time">%1$s</xliff:g> left</string>
  <!-- [CHAR_LIMIT=60] Label for estimated remaining duration of battery discharging -->
  <!-- [CHAR_LIMIT=60] Label for estimated remaining duration of battery discharging -->
    <string name="power_remaining_duration_only_enhanced">About <xliff:g id="time">^1</xliff:g> left based on your usage</string>
  <string name="power_remaining_duration_only_enhanced">About <xliff:g id="time">%1$s</xliff:g> left based on your usage</string>
  <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging -->
  <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging -->
    <string name="power_remaining_charging_duration_only"><xliff:g id="time">^1</xliff:g> left until fully charged</string>
  <string name="power_remaining_charging_duration_only"><xliff:g id="time">%1$s</xliff:g> left until fully charged</string>


  <!-- [CHAR_LIMIT=40] Short label for estimated remaining duration of battery charging/discharging -->
  <!-- [CHAR_LIMIT=40] Short label for estimated remaining duration of battery charging/discharging -->
    <string name="power_remaining_duration_only_short"><xliff:g id="time">^1</xliff:g> left</string>
  <string name="power_remaining_duration_only_short"><xliff:g id="time">%1$s</xliff:g> left</string>
    <!-- [CHAR_LIMIT=60] Short label for estimated remaining duration of battery charging/discharging -->

    <string name="power_remaining_duration_only_short_enhanced"><xliff:g id="time">^1</xliff:g> left based on your usage</string>
  <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount -->
  <string name="power_remaining_less_than_duration_only">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining</string>
  <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount with the percentage -->
  <string name="power_remaining_less_than_duration"><xliff:g id="level">%1$s</xliff:g> - Less than <xliff:g id="threshold">%2$s</xliff:g> remaining</string>

  <!-- Used to let users know that they have more than some amount of battery life remaining with percentage. ex: 75% - more than 1 day remaining [CHAR LIMIT = 80] -->
  <string name="power_remaining_more_than_subtext"><xliff:g id="level">%1$s</xliff:g>more than <xliff:g id="time_remaining">%2$s</xliff:g> remaining</string>
  <!-- Used to let users know that they have more than some amount of battery life remaining. ex: more than 1 day remaining [CHAR LIMIT = 40] -->
  <string name="power_remaining_only_more_than_subtext">more than <xliff:g id="time_remaining">%1$s</xliff:g> remaining</string>

  <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
  <string name="power_remaining_duration_only_shutdown_imminent" product="default">phone may shutdown soon</string>
  <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
  <string name="power_remaining_duration_only_shutdown_imminent" product="tablet">tablet may shutdown soon</string>
  <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
  <string name="power_remaining_duration_only_shutdown_imminent" product="device">device may shutdown soon</string>


  <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
  <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
    <string name="power_discharging_duration"><xliff:g id="level">^1</xliff:g> - about <xliff:g id="time">^2</xliff:g> left</string>
  <string name="power_discharging_duration"><xliff:g id="level">%1$s</xliff:g> - about <xliff:g id="time">%2$s</xliff:g> left</string>
  <!-- [CHAR_LIMIT=60] Label for battery level chart when discharging with duration and using enhanced estimate -->
  <!-- [CHAR_LIMIT=60] Label for battery level chart when discharging with duration and using enhanced estimate -->
    <string name="power_discharging_duration_enhanced"><xliff:g id="level">^1</xliff:g> - about <xliff:g id="time">^2</xliff:g> left based on your usage</string>
  <string name="power_discharging_duration_enhanced"><xliff:g id="level">%1$s</xliff:g> - about <xliff:g id="time">%2$s</xliff:g> left based on your usage</string>


    <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
  <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
    <string name="power_discharging_duration_short"><xliff:g id="level">^1</xliff:g> - <xliff:g id="time">^2</xliff:g> left</string>
  <string name="power_remaining_duration_shutdown_imminent" product="default"><xliff:g id="level">%1$s</xliff:g> - phone may shutdown soon</string>
  <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
  <string name="power_remaining_duration_shutdown_imminent" product="tablet"><xliff:g id="level">%1$s</xliff:g> - tablet may shutdown soon</string>
  <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
  <string name="power_remaining_duration_shutdown_imminent" product="device"><xliff:g id="level">%1$s</xliff:g> - device may shutdown soon</string>


    <!-- [CHAR_LIMIT=40] Label for battery level chart when charging -->
    <!-- [CHAR_LIMIT=40] Label for battery level chart when charging -->
    <string name="power_charging"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="state">%2$s</xliff:g></string>
    <string name="power_charging"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="state">%2$s</xliff:g></string>
    <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
    <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
    <string name="power_charging_duration"><xliff:g id="level">^1</xliff:g> - <xliff:g id="time">^2</xliff:g> until fully charged</string>
    <string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> until fully charged</string>


    <!-- Battery Info screen. Value for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
    <!-- Battery Info screen. Value for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
    <string name="battery_info_status_unknown">Unknown</string>
    <string name="battery_info_status_unknown">Unknown</string>
+143 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settingslib.utils;

import android.content.Context;
import android.icu.text.MeasureFormat;
import android.icu.text.MeasureFormat.FormatWidth;
import android.icu.util.Measure;
import android.icu.util.MeasureUnit;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.android.settingslib.R;
import com.android.settingslib.utils.StringUtil;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

/** Utility class for keeping power related strings consistent**/
public class PowerUtil {
    private static final long SEVEN_MINUTES_MILLIS = TimeUnit.MINUTES.toMillis(7);
    private static final long FIFTEEN_MINUTES_MILLIS = TimeUnit.MINUTES.toMillis(15);
    private static final long ONE_DAY_MILLIS = TimeUnit.DAYS.toMillis(1);

    /**
     * This method produces the text used in various places throughout the system to describe the
     * remaining battery life of the phone in a consistent manner.
     *
     * @param context
     * @param drainTimeMs The estimated time remaining before the phone dies in milliseconds.
     * @param percentageString An optional percentage of battery remaining string.
     * @param basedOnUsage Whether this estimate is based on usage or simple extrapolation.
     * @return a properly formatted and localized string describing how much time remains
     * before the battery runs out.
     */
    public static String getBatteryRemainingStringFormatted(Context context, long drainTimeMs,
            @Nullable String percentageString, boolean basedOnUsage) {
        if (drainTimeMs > 0) {
            if (drainTimeMs <= SEVEN_MINUTES_MILLIS) {
                // show a imminent shutdown warning if less than 7 minutes remain
                return getShutdownImminentString(context, percentageString);
            } else if (drainTimeMs <= FIFTEEN_MINUTES_MILLIS) {
                // show a less than 15 min remaining warning if appropriate
                CharSequence timeString = StringUtil.formatElapsedTime(context,
                        FIFTEEN_MINUTES_MILLIS,
                        false /* withSeconds */);
                return getUnderFifteenString(context, timeString, percentageString);
            } else if (drainTimeMs >= ONE_DAY_MILLIS) {
                // just say more than one day if over 24 hours
                return getMoreThanOneDayString(context, percentageString);
            } else {
                // show a regular time remaining string
                return getRegularTimeRemainingString(context, drainTimeMs,
                        percentageString, basedOnUsage);
            }
        }
        return null;
    }

    private static String getShutdownImminentString(Context context, String percentageString) {
        return TextUtils.isEmpty(percentageString)
                ? context.getString(R.string.power_remaining_duration_only_shutdown_imminent)
                : context.getString(
                        R.string.power_remaining_duration_shutdown_imminent,
                        percentageString);
    }

    private static String getUnderFifteenString(Context context, CharSequence timeString,
            String percentageString) {
        return TextUtils.isEmpty(percentageString)
                ? context.getString(R.string.power_remaining_less_than_duration_only, timeString)
                : context.getString(
                        R.string.power_remaining_less_than_duration,
                        percentageString,
                        timeString);

    }

    private static String getMoreThanOneDayString(Context context, String percentageString) {
        final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0);
        final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT);

        final Measure daysMeasure = new Measure(1, MeasureUnit.DAY);

        return TextUtils.isEmpty(percentageString)
                ? context.getString(R.string.power_remaining_only_more_than_subtext,
                        frmt.formatMeasures(daysMeasure))
                : context.getString(
                        R.string.power_remaining_more_than_subtext,
                        percentageString,
                        frmt.formatMeasures(daysMeasure));
    }

    private static String getRegularTimeRemainingString(Context context, long drainTimeMs,
            String percentageString, boolean basedOnUsage) {
        // round to the nearest 15 min to not appear oversly precise
        final long roundedTimeMs = roundToNearestThreshold(drainTimeMs,
                FIFTEEN_MINUTES_MILLIS);
        CharSequence timeString = StringUtil.formatElapsedTime(context,
                roundedTimeMs,
                false /* withSeconds */);
        if (TextUtils.isEmpty(percentageString)) {
            int id = basedOnUsage
                    ? R.string.power_remaining_duration_only_enhanced
                    : R.string.power_remaining_duration_only;
            return context.getString(id, timeString);
        } else {
            int id = basedOnUsage
                    ? R.string.power_discharging_duration_enhanced
                    : R.string.power_discharging_duration;
            return context.getString(id, percentageString, timeString);
        }
    }

    public static long convertUsToMs(long timeUs) {
        return timeUs / 1000;
    }

    public static long convertMsToUs(long timeMs) {
        return timeMs * 1000;
    }

    private static long roundToNearestThreshold(long drainTime, long threshold) {
        final long remainder = drainTime % threshold;
        if (remainder < threshold / 2) {
            return drainTime - remainder;
        } else {
            return drainTime - remainder + threshold;
        }
    }
}
+149 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settingslib.utils;

import android.content.Context;
import android.icu.text.MeasureFormat;
import android.icu.text.MeasureFormat.FormatWidth;
import android.icu.text.RelativeDateTimeFormatter;
import android.icu.text.RelativeDateTimeFormatter.RelativeUnit;
import android.icu.util.Measure;
import android.icu.util.MeasureUnit;
import android.icu.util.ULocale;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.TtsSpan;
import java.util.ArrayList;
import java.util.Locale;

/** Utility class for generally useful string methods **/
public class StringUtil {

  public static final int SECONDS_PER_MINUTE = 60;
  public static final int SECONDS_PER_HOUR = 60 * 60;
  public static final int SECONDS_PER_DAY = 24 * 60 * 60;

  /**
   * Returns elapsed time for the given millis, in the following format:
   * 2d 5h 40m 29s
   * @param context the application context
   * @param millis the elapsed time in milli seconds
   * @param withSeconds include seconds?
   * @return the formatted elapsed time
   */
  public static CharSequence formatElapsedTime(Context context, double millis,
          boolean withSeconds) {
      SpannableStringBuilder sb = new SpannableStringBuilder();
      int seconds = (int) Math.floor(millis / 1000);
      if (!withSeconds) {
          // Round up.
          seconds += 30;
      }

      int days = 0, hours = 0, minutes = 0;
      if (seconds >= SECONDS_PER_DAY) {
          days = seconds / SECONDS_PER_DAY;
          seconds -= days * SECONDS_PER_DAY;
      }
      if (seconds >= SECONDS_PER_HOUR) {
          hours = seconds / SECONDS_PER_HOUR;
          seconds -= hours * SECONDS_PER_HOUR;
      }
      if (seconds >= SECONDS_PER_MINUTE) {
          minutes = seconds / SECONDS_PER_MINUTE;
          seconds -= minutes * SECONDS_PER_MINUTE;
      }

      final ArrayList<Measure> measureList = new ArrayList(4);
      if (days > 0) {
          measureList.add(new Measure(days, MeasureUnit.DAY));
      }
      if (hours > 0) {
          measureList.add(new Measure(hours, MeasureUnit.HOUR));
      }
      if (minutes > 0) {
          measureList.add(new Measure(minutes, MeasureUnit.MINUTE));
      }
      if (withSeconds && seconds > 0) {
          measureList.add(new Measure(seconds, MeasureUnit.SECOND));
      }
      if (measureList.size() == 0) {
          // Everything addable was zero, so nothing was added. We add a zero.
          measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));
      }
      final Measure[] measureArray = measureList.toArray(new Measure[measureList.size()]);

      final Locale locale = context.getResources().getConfiguration().locale;
      final MeasureFormat measureFormat = MeasureFormat.getInstance(
              locale, FormatWidth.NARROW);
      sb.append(measureFormat.formatMeasures(measureArray));

      if (measureArray.length == 1 && MeasureUnit.MINUTE.equals(measureArray[0].getUnit())) {
          // Add ttsSpan if it only have minute value, because it will be read as "meters"
          final TtsSpan ttsSpan = new TtsSpan.MeasureBuilder().setNumber(minutes)
                  .setUnit("minute").build();
          sb.setSpan(ttsSpan, 0, sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
      }

      return sb;
  }

    /**
     * Returns relative time for the given millis in the past, in a short format such as "2 days
     * ago", "5 hr. ago", "40 min. ago", or "29 sec. ago".
     *
     * <p>The unit is chosen to have good information value while only using one unit. So 27 hours
     * and 50 minutes would be formatted as "28 hr. ago", while 50 hours would be formatted as
     * "2 days ago".
     *
     * @param context the application context
     * @param millis the elapsed time in milli seconds
     * @param withSeconds include seconds?
     * @return the formatted elapsed time
     */
    public static CharSequence formatRelativeTime(Context context, double millis,
            boolean withSeconds) {
        final int seconds = (int) Math.floor(millis / 1000);
        final RelativeUnit unit;
        final int value;
        if (withSeconds && seconds < 2 * SECONDS_PER_MINUTE) {
            unit = RelativeUnit.SECONDS;
            value = seconds;
        } else if (seconds < 2 * SECONDS_PER_HOUR) {
            unit = RelativeUnit.MINUTES;
            value = (seconds + SECONDS_PER_MINUTE / 2)
                    / SECONDS_PER_MINUTE;
        } else if (seconds < 2 * SECONDS_PER_DAY) {
            unit = RelativeUnit.HOURS;
            value = (seconds + SECONDS_PER_HOUR / 2)
                    / SECONDS_PER_HOUR;
        } else {
            unit = RelativeUnit.DAYS;
            value = (seconds + SECONDS_PER_DAY / 2)
                    / SECONDS_PER_DAY;
        }

        final Locale locale = context.getResources().getConfiguration().locale;
        final RelativeDateTimeFormatter formatter = RelativeDateTimeFormatter.getInstance(
                ULocale.forLocale(locale),
                null /* default NumberFormat */,
                RelativeDateTimeFormatter.Style.SHORT,
                android.icu.text.DisplayContext.CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE);

        return formatter.format(value, RelativeDateTimeFormatter.Direction.LAST, unit);
    }
}
+162 −0

File added.

Preview size limit exceeded, changes collapsed.

+213 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading