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

Commit 055bb614 authored by Dan Sandler's avatar Dan Sandler
Browse files

Percentage text now sits alongside the battery icon.

The old embedded percentage (introduced in change I6a3e7409) is hard
to read at status bar size, so we now draw it in a separate TextView to
the left (start) of the battery gauge. (The embedded code remains so
that it can be used by other places where the battery is drawn larger.)

The old system setting "status_bar_show_battery_percent" is still used
to control whether this percentage is shown, but note that it now
applies only to BatteryMeterView (i.e., the status bar) and not other
usages of BatteryMeterDrawable.

Bug: 32539932
Test: (manual) adb shell settings put system status_bar_show_battery_percent 1
Change-Id: Id298dba544f594b11269539284a2e8042fd4780b
parent 7183b690
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2017 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
  -->

<!-- Loaded into BatteryMeterView as necessary -->
<TextView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/battery_percentage_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:singleLine="true"
        android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
        android:textColor="?android:attr/textColorPrimary"
        android:gravity="center_vertical|start"
        android:paddingEnd="4dp"
        />
+3 −4
Original line number Diff line number Diff line
@@ -31,9 +31,8 @@
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/signal_cluster_margin_start"/>

    <!-- battery must be padded below to match assets -->
    <com.android.systemui.BatteryMeterView android:id="@+id/battery"
        android:layout_height="@dimen/status_bar_battery_icon_height"
        android:layout_width="@dimen/status_bar_battery_icon_width"
        android:layout_marginBottom="@dimen/battery_margin_bottom"/>
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        />
</LinearLayout>
 No newline at end of file
+0 −87
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.systemui;

import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings;
import com.android.settingslib.graph.BatteryMeterDrawableBase;
import com.android.systemui.statusbar.policy.BatteryController;

public class BatteryMeterDrawable extends BatteryMeterDrawableBase implements
        BatteryController.BatteryStateChangeCallback {

    public static final String SHOW_PERCENT_SETTING = "status_bar_show_battery_percent";

    private BatteryController mBatteryController;
    private SettingObserver mSettingObserver;

    public BatteryMeterDrawable(Context context, int frameColor) {
        super(context, frameColor);

        mSettingObserver = new SettingObserver(new Handler(mContext.getMainLooper()));
    }

    @Override
    public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
        setBatteryLevel(level);
        setPluggedIn(pluggedIn);
    }

    @Override
    public void onPowerSaveChanged(boolean isPowerSave) {
        setPowerSave(isPowerSave);
    }

    public void startListening() {
        mContext.getContentResolver().registerContentObserver(
                Settings.System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
        updateShowPercent();
        mBatteryController.addCallback(this);
    }

    public void stopListening() {
        mContext.getContentResolver().unregisterContentObserver(mSettingObserver);
        mBatteryController.removeCallback(this);
    }

    protected void updateShowPercent() {
        setShowPercent(0 != Settings.System.getInt(mContext.getContentResolver(),
                SHOW_PERCENT_SETTING, 0));
    }

    public void setBatteryController(BatteryController batteryController) {
        mBatteryController = batteryController;
        setPowerSave(mBatteryController.isPowerSave());
    }

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

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

}
+109 −9
Original line number Diff line number Diff line
@@ -23,10 +23,22 @@ import android.graphics.Rect;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.settingslib.graph.BatteryMeterDrawableBase;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
@@ -37,12 +49,22 @@ import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;

public class BatteryMeterView extends ImageView implements
import java.text.NumberFormat;

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

    private final BatteryMeterDrawable mDrawable;
    public static final String SHOW_PERCENT_SETTING = "status_bar_show_battery_percent";

    private final BatteryMeterDrawableBase mDrawable;
    private final String mSlotBattery;
    private final ImageView mBatteryIconView;
    private TextView mBatteryPercentView;

    private BatteryController mBatteryController;
    private SettingObserver mSettingObserver;
    private int mTextColor;
    private int mLevel;

    public BatteryMeterView(Context context) {
        this(context, null, 0);
@@ -55,16 +77,35 @@ public class BatteryMeterView extends ImageView implements
    public BatteryMeterView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        setOrientation(LinearLayout.HORIZONTAL);
        setGravity(Gravity.CENTER_VERTICAL | Gravity.START);

        TypedArray atts = context.obtainStyledAttributes(attrs, R.styleable.BatteryMeterView,
                defStyle, 0);
        final int frameColor = atts.getColor(R.styleable.BatteryMeterView_frameColor,
                context.getColor(R.color.batterymeter_frame_color));
        mDrawable = new BatteryMeterDrawable(context, frameColor);
        mDrawable = new BatteryMeterDrawableBase(context, frameColor);
        atts.recycle();

        mSettingObserver = new SettingObserver(new Handler(context.getMainLooper()));

        mSlotBattery = context.getString(
                com.android.internal.R.string.status_bar_battery);
        setImageDrawable(mDrawable);
        mBatteryIconView = new ImageView(context);
        mBatteryIconView.setImageDrawable(mDrawable);
        final MarginLayoutParams mlp = new MarginLayoutParams(
                getResources().getDimensionPixelSize(R.dimen.status_bar_battery_icon_width),
                getResources().getDimensionPixelSize(R.dimen.status_bar_battery_icon_height));
        mlp.setMargins(0, 0, 0,
                getResources().getDimensionPixelOffset(R.dimen.battery_margin_bottom));
        addView(mBatteryIconView, mlp);

        updateShowPercent();
    }

    // StatusBarIconController reaches in here and adjusts the layout parameters of the icon
    public ImageView getBatteryIconView() {
        return mBatteryIconView;
    }

    @Override
@@ -84,9 +125,10 @@ public class BatteryMeterView extends ImageView implements
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        mBatteryController = Dependency.get(BatteryController.class);
        mDrawable.setBatteryController(mBatteryController);
        mBatteryController.addCallback(this);
        mDrawable.startListening();
        getContext().getContentResolver().registerContentObserver(
                Settings.System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
        updateShowPercent();
        Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
        Dependency.get(ConfigurationController.class).addCallback(this);
    }
@@ -95,13 +137,17 @@ public class BatteryMeterView extends ImageView implements
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mBatteryController.removeCallback(this);
        mDrawable.stopListening();
        getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
        Dependency.get(TunerService.class).removeTunable(this);
        Dependency.get(ConfigurationController.class).removeCallback(this);
    }

    @Override
    public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
        mDrawable.setBatteryLevel(level);
        mDrawable.setPluggedIn(pluggedIn);
        mLevel = level;
        updatePercentText();
        setContentDescription(
                getContext().getString(charging ? R.string.accessibility_battery_level_charging
                        : R.string.accessibility_battery_level, level));
@@ -109,7 +155,41 @@ public class BatteryMeterView extends ImageView implements

    @Override
    public void onPowerSaveChanged(boolean isPowerSave) {
        mDrawable.setPowerSave(isPowerSave);
    }

    private TextView loadPercentView() {
        return (TextView) LayoutInflater.from(getContext())
                .inflate(R.layout.battery_percentage_view, null);
    }

    private void updatePercentText() {
        if (mBatteryPercentView != null) {
            mBatteryPercentView.setText(
                    NumberFormat.getPercentInstance().format(mLevel/100f));
        }
    }

    private void updateShowPercent() {
        final boolean showing = mBatteryPercentView != null;
        if (0 != Settings.System.getInt(getContext().getContentResolver(),
                BatteryMeterView.SHOW_PERCENT_SETTING, 0)) {
            if (!showing) {
                mBatteryPercentView = loadPercentView();
                if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
                updatePercentText();
                addView(mBatteryPercentView,
                        0,
                        new ViewGroup.LayoutParams(
                                LayoutParams.WRAP_CONTENT,
                                LayoutParams.MATCH_PARENT));
            }
        } else {
            if (showing) {
                removeView(mBatteryPercentView);
                mBatteryPercentView = null;
            }
        }
    }

    @Override
@@ -133,17 +213,37 @@ public class BatteryMeterView extends ImageView implements

        LinearLayout.LayoutParams scaledLayoutParams = new LinearLayout.LayoutParams(
                (int) (batteryWidth * iconScaleFactor), (int) (batteryHeight * iconScaleFactor));
        scaledLayoutParams.setMarginsRelative(0, 0, 0, marginBottom);
        scaledLayoutParams.setMargins(0, 0, 0, marginBottom);

        setLayoutParams(scaledLayoutParams);
        mBatteryIconView.setLayoutParams(scaledLayoutParams);
    }

    @Override
    public void onDarkChanged(Rect area, float darkIntensity, int tint) {
        mDrawable.setDarkIntensity(DarkIconDispatcher.isInArea(area, this) ? darkIntensity : 0);
        setTextColor(DarkIconDispatcher.getTint(area, this, tint));
    }

    public void setTextColor(int color) {
        mTextColor = color;
        if (mBatteryPercentView != null) {
            mBatteryPercentView.setTextColor(color);
        }
    }

    public void setRawColors(int fgColor, int bgColor) {
        mDrawable.setColors(fgColor, bgColor);
    }

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

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            super.onChange(selfChange, uri);
            updateShowPercent();
        }
    }
}
+8 −5
Original line number Diff line number Diff line
@@ -35,8 +35,8 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.BatteryInfo;
import com.android.settingslib.graph.BatteryMeterDrawableBase;
import com.android.settingslib.graph.UsageView;
import com.android.systemui.BatteryMeterDrawable;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QS.DetailAdapter;
@@ -155,7 +155,9 @@ public class BatteryTile extends QSTile<QSTile.State> implements BatteryControll

    private final class BatteryDetail implements DetailAdapter, OnClickListener,
            OnAttachStateChangeListener {
        private final BatteryMeterDrawable mDrawable = new BatteryMeterDrawable(mHost.getContext(),
        private final BatteryMeterDrawableBase mDrawable
                = new BatteryMeterDrawableBase(
                        mHost.getContext(),
                        mHost.getContext().getColor(R.color.batterymeter_frame_color));
        private View mCurrentView;

@@ -195,8 +197,9 @@ public class BatteryTile extends QSTile<QSTile.State> implements BatteryControll
            if (mCurrentView == null) {
                return;
            }
            mDrawable.onBatteryLevelChanged(100, false, false);
            mDrawable.onPowerSaveChanged(true);
            mDrawable.setBatteryLevel(100);
            mDrawable.setPluggedIn(false);
            mDrawable.setPowerSave(true);
            mDrawable.setShowPercent(false);
            ((ImageView) mCurrentView.findViewById(android.R.id.icon)).setImageDrawable(mDrawable);
            Checkable checkbox = (Checkable) mCurrentView.findViewById(android.R.id.toggle);
Loading