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

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

Merge "Add estimated time remaining text to QS"

parents 1c6deebb 4bf21dff
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -930,6 +930,8 @@
    <string name="power_discharge_by">Should last until about <xliff:g id="time">%1$s</xliff:g> (<xliff:g id="level">%2$s</xliff:g>)</string>
    <!-- [CHAR_LIMIT=100] Label for estimated time that phone will run out of battery -->
    <string name="power_discharge_by_only">Should last until about <xliff:g id="time">%1$s</xliff:g></string>
    <!-- [CHAR_LIMIT=100] Label for estimated time that phone will run out of battery -->
    <string name="power_discharge_by_only_short">Until <xliff:g id="time" example="12 PM">%1$s</xliff:g></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>
+48 −0
Original line number Diff line number Diff line
@@ -81,6 +81,30 @@ public class PowerUtil {
        return null;
    }

    /**
     * Method to produce a shortened string describing the remaining battery. Suitable for Quick
     * Settings and other areas where space is constrained.
     *
     * @param context context to fetch descriptions from
     * @param drainTimeMs The estimated time remaining before the phone dies in milliseconds.
     *
     * @return a properly formatted and localized short string describing how much time remains
     * before the battery runs out.
     */
    @Nullable
    public static String getBatteryRemainingShortStringFormatted(
            Context context, long drainTimeMs) {
        if (drainTimeMs <= 0) {
            return null;
        }

        if (drainTimeMs <= ONE_DAY_MILLIS) {
            return getRegularTimeRemainingShortString(context, drainTimeMs);
        } else {
            return getMoreThanOneDayShortString(context, drainTimeMs);
        }
    }

    private static String getShutdownImminentString(Context context, String percentageString) {
        return TextUtils.isEmpty(percentageString)
                ? context.getString(R.string.power_remaining_duration_only_shutdown_imminent)
@@ -120,6 +144,14 @@ public class PowerUtil {
        }
    }

    private static String getMoreThanOneDayShortString(Context context, long drainTimeMs) {
        final long roundedTimeMs = roundTimeToNearestThreshold(drainTimeMs, ONE_HOUR_MILLIS);
        CharSequence timeString = StringUtil.formatElapsedTime(context, roundedTimeMs,
                false /* withSeconds */);

        return context.getString(R.string.power_remaining_duration_only_short, timeString);
    }

    private static String getMoreThanTwoDaysString(Context context, String percentageString) {
        final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0);
        final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT);
@@ -162,6 +194,22 @@ public class PowerUtil {
        }
    }

    private static String getRegularTimeRemainingShortString(Context context, long drainTimeMs) {
        // Get the time of day we think device will die rounded to the nearest 15 min.
        final long roundedTimeOfDayMs =
                roundTimeToNearestThreshold(
                        System.currentTimeMillis() + drainTimeMs,
                        FIFTEEN_MINUTES_MILLIS);

        // convert the time to a properly formatted string.
        String skeleton = android.text.format.DateFormat.getTimeFormatString(context);
        DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton);
        Date date = Date.from(Instant.ofEpochMilli(roundedTimeOfDayMs));
        CharSequence timeString = fmt.format(date);

        return context.getString(R.string.power_discharge_by_only_short, timeString);
    }

    public static long convertUsToMs(long timeUs) {
        return timeUs / 1000;
    }
+15 −1
Original line number Diff line number Diff line
@@ -42,6 +42,20 @@
        android:id="@+id/statusIcons"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />
        android:layout_weight="1"
        android:paddingEnd="@dimen/signal_cluster_battery_padding" />

    <com.android.systemui.BatteryMeterView
        android:id="@+id/batteryRemainingIcon"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:paddingEnd="2dp" />

    <TextView
        android:id="@+id/batteryRemainingText"
        android:textAppearance="@style/TextAppearance.QS.TileLabel"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:gravity="center_vertical" />

</LinearLayout>
+28 −3
Original line number Diff line number Diff line
@@ -19,7 +19,10 @@ import static android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS;
import static android.app.StatusBarManager.DISABLE_NONE;
import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;

import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.animation.ArgbEvaluator;
import android.annotation.IntDef;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
@@ -55,15 +58,23 @@ import com.android.systemui.statusbar.policy.IconLogger;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.Utils.DisableStateTracker;
import com.android.systemui.R;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.text.NumberFormat;

public class BatteryMeterView extends LinearLayout implements
        BatteryStateChangeCallback, Tunable, DarkReceiver, ConfigurationListener {


    @Retention(SOURCE)
    @IntDef({MODE_DEFAULT, MODE_ON, MODE_OFF})
    public @interface BatteryPercentMode {}
    public static final int MODE_DEFAULT = 0;
    public static final int MODE_ON = 1;
    public static final int MODE_OFF = 2;

    private final BatteryMeterDrawableBase mDrawable;
    private final String mSlotBattery;
    private final ImageView mBatteryIconView;
@@ -74,6 +85,7 @@ public class BatteryMeterView extends LinearLayout implements
    private SettingObserver mSettingObserver;
    private int mTextColor;
    private int mLevel;
    private int mShowPercentMode = MODE_DEFAULT;
    private boolean mForceShowPercent;
    private boolean mShowPercentAvailable;

@@ -154,7 +166,19 @@ public class BatteryMeterView extends LinearLayout implements
    }

    public void setForceShowPercent(boolean show) {
        mForceShowPercent = show;
        setPercentShowMode(show ? MODE_ON : MODE_DEFAULT);
    }

    /**
     * Force a particular mode of showing percent
     *
     * 0 - No preference
     * 1 - Force on
     * 2 - Force off
     * @param mode desired mode (none, on, off)
     */
    public void setPercentShowMode(@BatteryPercentMode int mode) {
        mShowPercentMode = mode;
        updateShowPercent();
    }

@@ -273,7 +297,8 @@ public class BatteryMeterView extends LinearLayout implements
                .getIntForUser(getContext().getContentResolver(),
                SHOW_BATTERY_PERCENT, 0, mUser);

        if ((mShowPercentAvailable && systemSetting) || mForceShowPercent) {
        if ((mShowPercentAvailable && systemSetting && mShowPercentMode != MODE_OFF)
                || mShowPercentMode == MODE_ON) {
            if (!showing) {
                mBatteryPercentView = loadPercentView();
                if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
+81 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
package com.android.systemui.qs;

import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -28,12 +29,15 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Color;
import android.graphics.Rect;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.AlarmClock;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import android.text.format.DateUtils;
import android.util.AttributeSet;
@@ -68,6 +72,7 @@ import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
import com.android.systemui.statusbar.phone.StatusIconContainer;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
@@ -132,6 +137,9 @@ public class QuickStatusBarHeader extends RelativeLayout implements
    private DateView mDateView;
    private OngoingPrivacyChip mPrivacyChip;
    private Space mSpace;
    private BatteryMeterView mBatteryRemainingIcon;
    private TextView mBatteryRemainingText;
    private boolean mShowBatteryPercentAndEstimate;

    private NextAlarmController mAlarmController;
    private ZenModeController mZenController;
@@ -148,6 +156,9 @@ public class QuickStatusBarHeader extends RelativeLayout implements
    };
    private boolean mHasTopCutout = false;

    private final PercentSettingObserver mPercentSettingObserver =
            new PercentSettingObserver(new Handler(mContext.getMainLooper()));

    /**
     * Runnable for automatically fading out the long press tooltip (as if it were animating away).
     */
@@ -204,8 +215,12 @@ public class QuickStatusBarHeader extends RelativeLayout implements
        // Set the correct tint for the status icons so they contrast
        mIconManager.setTint(fillColor);

        mShowBatteryPercentAndEstimate = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_battery_percentage_setting_available);

        mBatteryMeterView = findViewById(R.id.battery);
        mBatteryMeterView.setForceShowPercent(true);
        mBatteryMeterView.setPercentShowMode(mShowBatteryPercentAndEstimate
                ? BatteryMeterView.MODE_ON : BatteryMeterView.MODE_OFF);
        mBatteryMeterView.setOnClickListener(this);
        mClockView = findViewById(R.id.clock);
        mClockView.setOnClickListener(this);
@@ -213,6 +228,15 @@ public class QuickStatusBarHeader extends RelativeLayout implements
        mPrivacyChip = findViewById(R.id.privacy_chip);
        mPrivacyChip.setOnClickListener(this);
        mSpace = findViewById(R.id.space);

        // Tint for the battery icons are handled in setupHost()
        mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon);
        mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_OFF);

        mBatteryRemainingText = findViewById(R.id.batteryRemainingText);
        mBatteryRemainingText.setTextColor(fillColor);

        updateShowPercent();
    }

    private void updateStatusText() {
@@ -371,6 +395,14 @@ public class QuickStatusBarHeader extends RelativeLayout implements
                .build();
    }

    private void updateBatteryRemainingText() {
        if (!mShowBatteryPercentAndEstimate) {
            return;
        }
        mBatteryRemainingText.setText(
                Dependency.get(BatteryController.class).getEstimatedTimeRemainingString());
    }

    public void setExpanded(boolean expanded) {
        if (mExpanded == expanded) return;
        mExpanded = expanded;
@@ -436,6 +468,9 @@ public class QuickStatusBarHeader extends RelativeLayout implements
        super.onAttachedToWindow();
        Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
        requestApplyInsets();
        mContext.getContentResolver().registerContentObserver(
                Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mPercentSettingObserver,
                ActivityManager.getCurrentUser());
    }

    @Override
@@ -475,6 +510,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements
    public void onDetachedFromWindow() {
        setListening(false);
        Dependency.get(StatusBarIconController.class).removeIconGroup(mIconManager);
        mContext.getContentResolver().unregisterContentObserver(mPercentSettingObserver);
        super.onDetachedFromWindow();
    }

@@ -491,6 +527,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements
            mAlarmController.addCallback(this);
            mContext.registerReceiver(mRingerReceiver,
                    new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
            updateBatteryRemainingText();
        } else {
            mZenController.removeCallback(this);
            mAlarmController.removeCallback(this);
@@ -660,6 +697,14 @@ public class QuickStatusBarHeader extends RelativeLayout implements
        // Use SystemUI context to get battery meter colors, and let it use the default tint (white)
        mBatteryMeterView.setColorsFromContext(mHost.getContext());
        mBatteryMeterView.onDarkChanged(new Rect(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT);

        Rect tintArea = new Rect(0, 0, 0, 0);
        int colorForeground = Utils.getColorAttrDefaultColor(getContext(),
                android.R.attr.colorForeground);
        float intensity = getColorIntensity(colorForeground);
        int fillColor = fillColorForIntensity(intensity, getContext());
        mBatteryRemainingIcon.setColorsFromContext(mHost.getContext());
        mBatteryRemainingIcon.onDarkChanged(tintArea, intensity, fillColor);
    }

    public void setCallback(Callback qsPanelCallback) {
@@ -692,4 +737,39 @@ public class QuickStatusBarHeader extends RelativeLayout implements
            lp.rightMargin = sideMargins;
        }
    }

    private void updateShowPercent() {
        final boolean systemSetting = 0 != Settings.System
                .getIntForUser(getContext().getContentResolver(),
                        SHOW_BATTERY_PERCENT, 0, ActivityManager.getCurrentUser());

        mShowBatteryPercentAndEstimate = systemSetting;

        updateBatteryViews();
    }

    private void updateBatteryViews() {
        if (mShowBatteryPercentAndEstimate) {
            mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_ON);
            mBatteryRemainingIcon.setVisibility(View.VISIBLE);
            mBatteryRemainingText.setVisibility(View.VISIBLE);
            updateBatteryRemainingText();
        } else {
            mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_OFF);
            mBatteryRemainingIcon.setVisibility(View.GONE);
            mBatteryRemainingText.setVisibility(View.GONE);
        }
    }

    private final class PercentSettingObserver extends ContentObserver {
        PercentSettingObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            super.onChange(selfChange, uri);
            updateShowPercent();
        }
    }
}
Loading