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

Commit 549dbd60 authored by John Spurlock's avatar John Spurlock Committed by Android (Google) Code Review
Browse files

Merge "QS: Cellular usage warning marker + policy cycle." into lmp-dev

parents 9fb7b07c d11a19b8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
    <color name="qs_detail_empty">#24B0BEC5</color><!-- 14% blue grey 200-->
    <color name="data_usage_secondary">#99FFFFFF</color><!-- 60% white -->
    <color name="data_usage_graph_track">#33FFFFFF</color><!-- 20% white -->
    <color name="data_usage_graph_warning">#FFFFFFFF</color>
    <color name="status_bar_clock_color">#33FFFFFF</color>

    <!-- Tint color for the content on the notification overflow card. -->
+2 −0
Original line number Diff line number Diff line
@@ -572,6 +572,8 @@
    <string name="quick_settings_cellular_detail_data_used"><xliff:g id="data_used" example="2.0 GB">%s</xliff:g> used</string>
    <!-- QuickSettings: Cellular detail panel, data limit format string [CHAR LIMIT=NONE] -->
    <string name="quick_settings_cellular_detail_data_limit"><xliff:g id="data_limit" example="2.0 GB">%s</xliff:g> limit</string>
    <!-- QuickSettings: Cellular detail panel, data warning format string [CHAR LIMIT=NONE] -->
    <string name="quick_settings_cellular_detail_data_warning"><xliff:g id="data_limit" example="2.0 GB">%s</xliff:g> warning</string>

    <!-- Recents: The empty recents string. [CHAR LIMIT=NONE] -->
    <string name="recents_empty_message">No recent apps</string>
+29 −33
Original line number Diff line number Diff line
@@ -28,34 +28,34 @@ import com.android.systemui.R;

public class DataUsageGraph extends View {

    private final int mBackgroundColor;
    private final int mTrackColor;
    private final int mUsageColor;
    private final int mOverlimitColor;
    private final int mWarningColor;
    private final int mMarkerWidth;
    private final RectF mTmpRect = new RectF();
    private final Paint mTmpPaint = new Paint();

    private long mMaxLevel = 1;
    private long mLimitLevel;
    private long mWarningLevel;
    private long mUsageLevel;
    private long mMaxLevel;

    public DataUsageGraph(Context context, AttributeSet attrs) {
        super(context, attrs);
        final Resources res = context.getResources();
        mBackgroundColor = res.getColor(R.color.system_primary_color);
        mTrackColor = res.getColor(R.color.data_usage_graph_track);
        mUsageColor = res.getColor(R.color.system_accent_color);
        mOverlimitColor = res.getColor(R.color.system_warning_color);
        mWarningColor = res.getColor(R.color.data_usage_graph_warning);
        mMarkerWidth = res.getDimensionPixelSize(R.dimen.data_usage_graph_marker_width);
    }

    public void setLevels(long maxLevel, long limitLevel, long warningLevel, long usageLevel) {
        mMaxLevel = Math.max(maxLevel, 1);
        mLimitLevel = limitLevel;
        mWarningLevel = warningLevel;
        mUsageLevel = usageLevel;
    public void setLevels(long limitLevel, long warningLevel, long usageLevel) {
        mLimitLevel = Math.max(0, limitLevel);
        mWarningLevel = Math.max(0, warningLevel);
        mUsageLevel = Math.max(0, usageLevel);
        mMaxLevel = Math.max(Math.max(Math.max(mLimitLevel, mWarningLevel), mUsageLevel), 1);
        postInvalidate();
    }

@@ -68,21 +68,22 @@ public class DataUsageGraph extends View {
        final int w = getWidth();
        final int h = getHeight();

        final boolean overLimit = mLimitLevel > 0 && mUsageLevel > mLimitLevel;
        float usageRight = w * (mUsageLevel / (float) mMaxLevel);
        if (overLimit) {
            // compute the gap
            usageRight = w * (mLimitLevel / (float) mMaxLevel) - (mMarkerWidth / 2);
            usageRight = Math.min(Math.max(usageRight, mMarkerWidth), w - mMarkerWidth * 2);

            // draw overlimit
            r.set(usageRight + mMarkerWidth, 0, w, h);
            p.setColor(mOverlimitColor);
            canvas.drawRect(r, p);
        } else {
            // draw track
            r.set(0, 0, w, h);
            p.setColor(mTrackColor);
            canvas.drawRect(r, p);

        final boolean hasLimit = mLimitLevel > 0;
        final boolean overLimit = hasLimit && mUsageLevel > mLimitLevel;

        final long maxLevel = hasLimit ? Math.max(mUsageLevel, mLimitLevel) : mMaxLevel;
        final long usageLevel = hasLimit ? Math.min(mUsageLevel, mLimitLevel) : mUsageLevel;
        float usageRight = w * (usageLevel / (float) maxLevel);
        if (overLimit) {
            usageRight -= (mMarkerWidth / 2);
            usageRight = Math.min(usageRight, w - mMarkerWidth * 2);
            usageRight = Math.max(usageRight, mMarkerWidth);
        }

        // draw usage
@@ -90,16 +91,11 @@ public class DataUsageGraph extends View {
        p.setColor(mUsageColor);
        canvas.drawRect(r, p);

        if (overLimit) {
            // draw gap
            r.set(usageRight, 0, usageRight + mMarkerWidth, h);
            p.setColor(mBackgroundColor);
            canvas.drawRect(r, p);

            // draw overlimit
            r.set(usageRight + mMarkerWidth, 0, w, h);
            p.setColor(mOverlimitColor);
        // draw warning marker
        float warningLeft = w * (mWarningLevel / (float) mMaxLevel) - mMarkerWidth / 2;
        warningLeft = Math.min(Math.max(warningLeft, 0), w - mMarkerWidth);
        r.set(warningLeft, 0, warningLeft + mMarkerWidth, h);
        p.setColor(mWarningColor);
        canvas.drawRect(r, p);
    }
}
}
+13 −7
Original line number Diff line number Diff line
@@ -216,21 +216,27 @@ public class CellularTile extends QSTile<QSTile.SignalState> {
            final DataUsageInfo info = mController.getDataUsageInfo();
            if (info == null) return v;
            final Resources res = mContext.getResources();
            int titleId;
            long bytes;
            final int titleId;
            final long bytes;
            int usageColor = R.color.system_accent_color;
            String top = null, bottom = null;
            if (info.limitLevel <= 0) { // no limit
            final String top;
            String bottom = null;
            if (info.usageLevel < info.warningLevel || info.limitLevel <= 0) {
                // under warning, or no limit
                titleId = R.string.quick_settings_cellular_detail_data_usage;
                bytes = info.usageLevel;
            } else if (info.usageLevel <= info.limitLevel) { // under limit
                top = res.getString(R.string.quick_settings_cellular_detail_data_warning,
                        formatBytes(info.warningLevel));
            } else if (info.usageLevel <= info.limitLevel) {
                // over warning, under limit
                titleId = R.string.quick_settings_cellular_detail_remaining_data;
                bytes = info.limitLevel - info.usageLevel;
                top = res.getString(R.string.quick_settings_cellular_detail_data_used,
                        formatBytes(info.usageLevel));
                bottom = res.getString(R.string.quick_settings_cellular_detail_data_limit,
                        formatBytes(info.limitLevel));
            } else { // over limit
            } else {
                // over limit
                titleId = R.string.quick_settings_cellular_detail_over_limit;
                bytes = info.usageLevel - info.limitLevel;
                top = res.getString(R.string.quick_settings_cellular_detail_data_used,
@@ -246,7 +252,7 @@ public class CellularTile extends QSTile<QSTile.SignalState> {
            usage.setText(formatBytes(bytes));
            usage.setTextColor(res.getColor(usageColor));
            final DataUsageGraph graph = (DataUsageGraph) v.findViewById(R.id.usage_graph);
            graph.setLevels(info.maxLevel, info.limitLevel, info.warningLevel, info.usageLevel);
            graph.setLevels(info.limitLevel, info.warningLevel, info.usageLevel);
            final TextView carrier = (TextView) v.findViewById(R.id.usage_carrier_text);
            carrier.setText(info.carrier);
            final TextView period = (TextView) v.findViewById(R.id.usage_period_text);
+50 −8
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
import static android.telephony.TelephonyManager.SIM_STATE_READY;
import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
import static android.text.format.DateUtils.FORMAT_SHOW_DATE;

import android.content.Context;
import android.net.ConnectivityManager;
@@ -33,19 +35,23 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.Log;

import com.android.systemui.statusbar.policy.NetworkController.DataUsageInfo;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class MobileDataController {
    private static final String TAG = "MobileDataController";
    private static final boolean DEBUG = true;
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    private static final SimpleDateFormat MMM_D = new SimpleDateFormat("MMM d");
    private static final long DEFAULT_WARNING_LEVEL = 2L * 1024 * 1024 * 1024;
    private static final int FIELDS = FIELD_RX_BYTES | FIELD_TX_BYTES;
    private static final StringBuilder PERIOD_BUILDER = new StringBuilder(50);
    private static final java.util.Formatter PERIOD_FORMATTER = new java.util.Formatter(
            PERIOD_BUILDER, Locale.getDefault());

    private final Context mContext;
    private final TelephonyManager mTelephonyManager;
@@ -87,6 +93,13 @@ public class MobileDataController {
        return null;
    }

    private static Time addMonth(Time t, int months) {
        final Time rt = new Time(t);
        rt.set(t.monthDay, t.month + months, t.year);
        rt.normalize(false);
        return rt;
    }

    public DataUsageInfo getDataUsageInfo() {
        final String subscriberId = getActiveSubscriberId(mContext);
        if (subscriberId == null) {
@@ -101,9 +114,28 @@ public class MobileDataController {
        try {
            final NetworkStatsHistory history = mSession.getHistoryForNetwork(template, FIELDS);
            final long now = System.currentTimeMillis();
            // period = last 4 wks for now
            final long start = now - DateUtils.WEEK_IN_MILLIS * 4;
            final long end = now;
            final long start, end;
            if (policy != null && policy.cycleDay > 0) {
                // period = determined from cycleDay
                if (DEBUG) Log.d(TAG, "Cycle day=" + policy.cycleDay + " tz="
                        + policy.cycleTimezone);
                final Time nowTime = new Time(policy.cycleTimezone);
                nowTime.setToNow();
                final Time policyTime = new Time(nowTime);
                policyTime.set(policy.cycleDay, policyTime.month, policyTime.year);
                policyTime.normalize(false);
                if (nowTime.after(policyTime)) {
                    start = policyTime.toMillis(false);
                    end = addMonth(policyTime, 1).toMillis(false);
                } else {
                    start = addMonth(policyTime, -1).toMillis(false);
                    end = policyTime.toMillis(false);
                }
            } else {
                // period = last 4 wks
                end = now;
                start = now - DateUtils.WEEK_IN_MILLIS * 4;
            }
            final long callStart = System.currentTimeMillis();
            final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
            final long callEnd = System.currentTimeMillis();
@@ -115,12 +147,13 @@ public class MobileDataController {
            }
            final long totalBytes = entry.rxBytes + entry.txBytes;
            final DataUsageInfo usage = new DataUsageInfo();
            usage.maxLevel = (long) (totalBytes / .4);
            usage.usageLevel = totalBytes;
            usage.period = MMM_D.format(new Date(start)) + " - " + MMM_D.format(new Date(end));
            usage.period = formatDateRange(start, end);
            if (policy != null) {
                usage.limitLevel = policy.limitBytes > 0 ? policy.limitBytes : 0;
                usage.warningLevel = policy.warningBytes > 0 ? policy.warningBytes : 0;
            } else {
                usage.warningLevel = DEFAULT_WARNING_LEVEL;
            }
            return usage;
        } catch (RemoteException e) {
@@ -178,6 +211,15 @@ public class MobileDataController {
        return actualSubscriberId;
    }

    private String formatDateRange(long start, long end) {
        final int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH;
        synchronized (PERIOD_BUILDER) {
            PERIOD_BUILDER.setLength(0);
            return DateUtils.formatDateRange(mContext, PERIOD_FORMATTER, start, end, flags, null)
                    .toString();
        }
    }

    public interface Callback {
        void onMobileDataEnabled(boolean enabled);
    }
Loading