Loading packages/SystemUI/res/values/colors.xml +1 −0 Original line number Diff line number Diff line Loading @@ -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. --> Loading packages/SystemUI/res/values/strings.xml +2 −0 Original line number Diff line number Diff line Loading @@ -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> Loading packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java +29 −33 Original line number Diff line number Diff line Loading @@ -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(); } Loading @@ -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 Loading @@ -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); } } } packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +13 −7 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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); Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataController.java +50 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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(); Loading @@ -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) { Loading Loading @@ -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 Loading
packages/SystemUI/res/values/colors.xml +1 −0 Original line number Diff line number Diff line Loading @@ -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. --> Loading
packages/SystemUI/res/values/strings.xml +2 −0 Original line number Diff line number Diff line Loading @@ -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> Loading
packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java +29 −33 Original line number Diff line number Diff line Loading @@ -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(); } Loading @@ -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 Loading @@ -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); } } }
packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +13 −7 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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); Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataController.java +50 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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(); Loading @@ -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) { Loading Loading @@ -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