summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2011-07-27 22:08:05 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-07-27 22:08:05 -0700
commit18d2b15b80a5926f8a64459f98c955d45029c453 (patch)
tree1ff3ef75435068afc20de6683e3aa189515e2608 /src
parenta75a5ea80b9651472e9209364987460eb561ec64 (diff)
parentd360e5efaaf4ea5f487a84787210a6c5d26337a8 (diff)
downloadpackages_apps_settings-18d2b15b80a5926f8a64459f98c955d45029c453.zip
packages_apps_settings-18d2b15b80a5926f8a64459f98c955d45029c453.tar.gz
packages_apps_settings-18d2b15b80a5926f8a64459f98c955d45029c453.tar.bz2
Merge "Data usage fit and finish."
Diffstat (limited to 'src')
-rw-r--r--src/com/android/settings/DataUsageSummary.java113
-rw-r--r--src/com/android/settings/widget/ChartSweepView.java85
-rw-r--r--src/com/android/settings/widget/DataUsageChartView.java51
3 files changed, 174 insertions, 75 deletions
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java
index 0b5d295..d87080f 100644
--- a/src/com/android/settings/DataUsageSummary.java
+++ b/src/com/android/settings/DataUsageSummary.java
@@ -128,6 +128,7 @@ public class DataUsageSummary extends Fragment {
private static final boolean LOGD = true;
// TODO: remove this testing code
+ private static final boolean TEST_ANIM = false;
private static final boolean TEST_RADIOS = false;
private static final String TEST_RADIOS_PROP = "test.radios";
@@ -175,10 +176,12 @@ public class DataUsageSummary extends Fragment {
private CheckBox mDisableAtLimit;
private View mDisableAtLimitView;
+ private View mCycleView;
private Spinner mCycleSpinner;
private CycleAdapter mCycleAdapter;
private DataUsageChartView mChart;
+ private TextView mUsageSummary;
private View mAppDetail;
private TextView mAppTitle;
@@ -272,7 +275,8 @@ public class DataUsageSummary extends Fragment {
}
// bind cycle dropdown
- mCycleSpinner = (Spinner) mHeader.findViewById(R.id.cycles);
+ mCycleView = mHeader.findViewById(R.id.cycles);
+ mCycleSpinner = (Spinner) mCycleView.findViewById(R.id.cycles_spinner);
mCycleAdapter = new CycleAdapter(context);
mCycleSpinner.setAdapter(mCycleAdapter);
mCycleSpinner.setOnItemSelectedListener(mCycleListener);
@@ -282,12 +286,12 @@ public class DataUsageSummary extends Fragment {
{
// bind app detail controls
- mAppDetail = view.findViewById(R.id.app_detail);
- mAppTitle = (TextView) view.findViewById(R.id.app_title);
- mAppSubtitle = (TextView) view.findViewById(R.id.app_subtitle);
- mAppSwitches = (LinearLayout) view.findViewById(R.id.app_switches);
+ mAppDetail = mHeader.findViewById(R.id.app_detail);
+ mAppTitle = (TextView) mAppDetail.findViewById(R.id.app_title);
+ mAppSubtitle = (TextView) mAppDetail.findViewById(R.id.app_subtitle);
+ mAppSwitches = (LinearLayout) mAppDetail.findViewById(R.id.app_switches);
- mAppSettings = (Button) view.findViewById(R.id.app_settings);
+ mAppSettings = (Button) mAppDetail.findViewById(R.id.app_settings);
mAppSettings.setOnClickListener(mAppSettingsListener);
mAppRestrict = new CheckBox(inflater.getContext());
@@ -300,8 +304,10 @@ public class DataUsageSummary extends Fragment {
mAppSwitches.addView(mAppRestrictView);
}
+ mUsageSummary = (TextView) mHeader.findViewById(R.id.usage_summary);
+
// only assign layout transitions once first layout is finished
- mHeader.getViewTreeObserver().addOnGlobalLayoutListener(mFirstLayoutListener);
+ mListView.getViewTreeObserver().addOnGlobalLayoutListener(mFirstLayoutListener);
mAdapter = new DataUsageAdapter();
mListView.setOnItemClickListener(mListListener);
@@ -443,19 +449,28 @@ public class DataUsageSummary extends Fragment {
private OnGlobalLayoutListener mFirstLayoutListener = new OnGlobalLayoutListener() {
/** {@inheritDoc} */
public void onGlobalLayout() {
- mHeader.getViewTreeObserver().removeGlobalOnLayoutListener(mFirstLayoutListener);
+ mListView.getViewTreeObserver().removeGlobalOnLayoutListener(mFirstLayoutListener);
- mTabsContainer.setLayoutTransition(new LayoutTransition());
- mHeader.setLayoutTransition(new LayoutTransition());
- mNetworkSwitchesContainer.setLayoutTransition(new LayoutTransition());
+ mTabsContainer.setLayoutTransition(buildLayoutTransition());
+ mHeader.setLayoutTransition(buildLayoutTransition());
+ mNetworkSwitchesContainer.setLayoutTransition(buildLayoutTransition());
- final LayoutTransition chartTransition = new LayoutTransition();
+ final LayoutTransition chartTransition = buildLayoutTransition();
chartTransition.setStartDelay(LayoutTransition.APPEARING, 0);
chartTransition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
mChart.setLayoutTransition(chartTransition);
}
};
+ private static LayoutTransition buildLayoutTransition() {
+ final LayoutTransition transition = new LayoutTransition();
+ if (TEST_ANIM) {
+ transition.setDuration(1500);
+ }
+ transition.setAnimateParentHierarchy(false);
+ return transition;
+ }
+
/**
* Rebuild all tabs based on {@link NetworkPolicyEditor} and
* {@link #mShowWifi}, hiding the tabs entirely when applicable. Selects
@@ -668,7 +683,7 @@ public class DataUsageSummary extends Fragment {
updateDetailData();
final Context context = getActivity();
- if (NetworkPolicyManager.isUidValidForPolicy(context, mUid)) {
+ if (NetworkPolicyManager.isUidValidForPolicy(context, mUid) && !getRestrictBackground()) {
mAppRestrictView.setVisibility(View.VISIBLE);
mAppRestrict.setChecked(getAppRestrictBackground());
@@ -710,13 +725,22 @@ public class DataUsageSummary extends Fragment {
}
private boolean getRestrictBackground() {
- return !mConnService.getBackgroundDataSetting();
+ try {
+ return mPolicyService.getRestrictBackground();
+ } catch (RemoteException e) {
+ Log.w(TAG, "problem talking with policy service: " + e);
+ return false;
+ }
}
private void setRestrictBackground(boolean restrictBackground) {
if (LOGD) Log.d(TAG, "setRestrictBackground()");
- mConnService.setBackgroundDataSetting(!restrictBackground);
- mMenuRestrictBackground.setChecked(restrictBackground);
+ try {
+ mPolicyService.setRestrictBackground(restrictBackground);
+ mMenuRestrictBackground.setChecked(restrictBackground);
+ } catch (RemoteException e) {
+ Log.w(TAG, "problem talking with policy service: " + e);
+ }
}
private boolean getAppRestrictBackground() {
@@ -732,7 +756,7 @@ public class DataUsageSummary extends Fragment {
}
private void setAppRestrictBackground(boolean restrictBackground) {
- if (LOGD) Log.d(TAG, "setRestrictBackground()");
+ if (LOGD) Log.d(TAG, "setAppRestrictBackground()");
try {
mPolicyService.setUidPolicy(
mUid, restrictBackground ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
@@ -909,7 +933,7 @@ public class DataUsageSummary extends Fragment {
// update chart to show selected cycle, and update detail data
// to match updated sweep bounds.
- mChart.setVisibleRange(cycle.start, cycle.end, mHistory.getEnd());
+ mChart.setVisibleRange(cycle.start, cycle.end);
updateDetailData();
}
@@ -932,28 +956,40 @@ public class DataUsageSummary extends Fragment {
final long start = mChart.getInspectStart();
final long end = mChart.getInspectEnd();
+ final long now = System.currentTimeMillis();
+
+ final Context context = getActivity();
+ final NetworkStatsHistory.Entry entry;
if (isAppDetailMode()) {
if (mDetailHistory != null) {
- final Context context = mChart.getContext();
- final long now = System.currentTimeMillis();
- final NetworkStatsHistory.Entry entry = mDetailHistory.getValues(
- start, end, now, null);
+ entry = mDetailHistory.getValues(start, end, now, null);
mAppSubtitle.setText(
getString(R.string.data_usage_received_sent,
Formatter.formatFileSize(context, entry.rxBytes),
Formatter.formatFileSize(context, entry.txBytes)));
+ } else {
+ entry = null;
}
getLoaderManager().destroyLoader(LOADER_SUMMARY);
} else {
+ entry = mHistory.getValues(start, end, now, null);
+
// kick off loader for detailed stats
getLoaderManager().restartLoader(LOADER_SUMMARY,
SummaryForAllUidLoader.buildArgs(mTemplate, start, end), mSummaryForAllUid);
}
+
+ final long totalBytes = entry != null ? entry.rxBytes + entry.txBytes : 0;
+ final String totalPhrase = Formatter.formatFileSize(context, totalBytes);
+ final String rangePhrase = formatDateRangeUtc(context, start, end);
+
+ mUsageSummary.setText(
+ getString(R.string.data_usage_total_during_range, totalPhrase, rangePhrase));
}
private final LoaderCallbacks<NetworkStats> mSummaryForAllUid = new LoaderCallbacks<
@@ -1022,10 +1058,6 @@ public class DataUsageSummary extends Fragment {
public long start;
public long end;
- private static final StringBuilder sBuilder = new StringBuilder(50);
- private static final java.util.Formatter sFormatter = new java.util.Formatter(
- sBuilder, Locale.getDefault());
-
CycleItem(CharSequence label) {
this.label = label;
}
@@ -1036,21 +1068,30 @@ public class DataUsageSummary extends Fragment {
this.end = end;
}
- private static String formatDateRangeUtc(Context context, long start, long end) {
- synchronized (sBuilder) {
- sBuilder.setLength(0);
- return DateUtils.formatDateRange(context, sFormatter, start, end,
- DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH,
- Time.TIMEZONE_UTC).toString();
- }
- }
-
@Override
public String toString() {
return label.toString();
}
}
+ private static final StringBuilder sBuilder = new StringBuilder(50);
+ private static final java.util.Formatter sFormatter = new java.util.Formatter(
+ sBuilder, Locale.getDefault());
+
+ private static String formatDateRangeUtc(Context context, long start, long end) {
+ synchronized (sBuilder) {
+ int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH;
+ if (Time.getJulianDay(start, 0) == Time.getJulianDay(end, 0)) {
+ // when times are on same day, include time detail
+ flags |= DateUtils.FORMAT_SHOW_TIME;
+ }
+
+ sBuilder.setLength(0);
+ return DateUtils.formatDateRange(
+ context, sFormatter, start, end, flags, Time.TIMEZONE_UTC).toString();
+ }
+ }
+
/**
* Special-case data usage cycle that triggers dialog to change
* {@link NetworkPolicy#cycleDay}.
@@ -1366,7 +1407,7 @@ public class DataUsageSummary extends Fragment {
/**
* Dialog to request user confirmation before setting
- * {@link ConnectivityManager#setBackgroundDataSetting(boolean)}.
+ * {@link INetworkPolicyManager#setRestrictBackground(boolean)}.
*/
public static class ConfirmRestrictFragment extends DialogFragment {
public static void show(DataUsageSummary parent) {
diff --git a/src/com/android/settings/widget/ChartSweepView.java b/src/com/android/settings/widget/ChartSweepView.java
index 4e37657..99c35bd 100644
--- a/src/com/android/settings/widget/ChartSweepView.java
+++ b/src/com/android/settings/widget/ChartSweepView.java
@@ -61,8 +61,11 @@ public class ChartSweepView extends FrameLayout {
private ChartAxis mAxis;
private long mValue;
- private ChartSweepView mClampAfter;
- private ChartSweepView mClampBefore;
+ private long mValidAfter;
+ private long mValidBefore;
+ private ChartSweepView mValidAfterDynamic;
+ private ChartSweepView mValidBeforeDynamic;
+ private long mValidBufferArea;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
@@ -259,12 +262,25 @@ public class ChartSweepView extends FrameLayout {
}
}
- public void setClampAfter(ChartSweepView clampAfter) {
- mClampAfter = clampAfter;
+ /**
+ * Set valid range this sweep can move within, in {@link #mAxis} values. The
+ * most restrictive combination of all valid ranges is used.
+ */
+ public void setValidRange(long validAfter, long validBefore) {
+ mValidAfter = validAfter;
+ mValidBefore = validBefore;
}
- public void setClampBefore(ChartSweepView clampBefore) {
- mClampBefore = clampBefore;
+ /**
+ * Set valid range this sweep can move within, defined by the given
+ * {@link ChartSweepView}. The most restrictive combination of all valid
+ * ranges is used.
+ */
+ public void setValidRangeDynamic(
+ ChartSweepView validAfter, ChartSweepView validBefore, long bufferArea) {
+ mValidAfterDynamic = validAfter;
+ mValidBeforeDynamic = validBefore;
+ mValidBufferArea = bufferArea;
}
@Override
@@ -285,6 +301,12 @@ public class ChartSweepView extends FrameLayout {
if (accept) {
mTracking = event.copy();
+
+ // starting drag should activate entire chart
+ if (!parent.isActivated()) {
+ parent.setActivated(true);
+ }
+
return true;
} else {
return false;
@@ -336,31 +358,52 @@ public class ChartSweepView extends FrameLayout {
}
}
+ @Override
+ public void addOnLayoutChangeListener(OnLayoutChangeListener listener) {
+ // ignored to keep LayoutTransition from animating us
+ }
+
+ @Override
+ public void removeOnLayoutChangeListener(OnLayoutChangeListener listener) {
+ // ignored to keep LayoutTransition from animating us
+ }
+
+ private long getValidAfterValue() {
+ final ChartSweepView dynamic = mValidAfterDynamic;
+ final boolean dynamicEnabled = dynamic != null && dynamic.isEnabled();
+ return Math.max(mValidAfter,
+ dynamicEnabled ? dynamic.getValue() + mValidBufferArea : Long.MIN_VALUE);
+ }
+
+ private long getValidBeforeValue() {
+ final ChartSweepView dynamic = mValidBeforeDynamic;
+ final boolean dynamicEnabled = dynamic != null && dynamic.isEnabled();
+ return Math.min(mValidBefore,
+ dynamicEnabled ? dynamic.getValue() - mValidBufferArea : Long.MAX_VALUE);
+ }
+
/**
* Compute {@link Rect} in {@link #getParent()} coordinates that we should
- * be clamped inside of, usually from {@link #setClampAfter(ChartSweepView)}
+ * be clamped inside of, usually from {@link #setValidRange(long, long)}
* style rules.
*/
private Rect computeClampRect(Rect parentContent) {
final Rect clampRect = new Rect(parentContent);
- final ChartSweepView after = mClampAfter;
- final ChartSweepView before = mClampBefore;
+ float validAfterPoint = mAxis.convertToPoint(getValidAfterValue());
+ float validBeforePoint = mAxis.convertToPoint(getValidBeforeValue());
+ if (validAfterPoint > validBeforePoint) {
+ float swap = validBeforePoint;
+ validBeforePoint = validAfterPoint;
+ validAfterPoint = swap;
+ }
if (mFollowAxis == VERTICAL) {
- if (after != null) {
- clampRect.top += after.getPoint();
- }
- if (before != null) {
- clampRect.bottom -= clampRect.height() - before.getPoint();
- }
+ clampRect.bottom = clampRect.top + (int) validBeforePoint;
+ clampRect.top += validAfterPoint;
} else {
- if (after != null) {
- clampRect.left += after.getPoint();
- }
- if (before != null) {
- clampRect.right -= clampRect.width() - before.getPoint();
- }
+ clampRect.right = clampRect.left + (int) validBeforePoint;
+ clampRect.left += validAfterPoint;
}
return clampRect;
}
diff --git a/src/com/android/settings/widget/DataUsageChartView.java b/src/com/android/settings/widget/DataUsageChartView.java
index affede0..839171e 100644
--- a/src/com/android/settings/widget/DataUsageChartView.java
+++ b/src/com/android/settings/widget/DataUsageChartView.java
@@ -16,6 +16,8 @@
package com.android.settings.widget;
+import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+
import android.content.Context;
import android.content.res.Resources;
import android.net.NetworkPolicy;
@@ -47,6 +49,8 @@ public class DataUsageChartView extends ChartView {
private ChartNetworkSeriesView mSeries;
private ChartNetworkSeriesView mDetailSeries;
+ private NetworkStatsHistory mHistory;
+
private ChartSweepView mSweepLeft;
private ChartSweepView mSweepRight;
private ChartSweepView mSweepWarning;
@@ -88,10 +92,14 @@ public class DataUsageChartView extends ChartView {
mSweepWarning = (ChartSweepView) findViewById(R.id.sweep_warning);
// prevent sweeps from crossing each other
- mSweepLeft.setClampBefore(mSweepRight);
- mSweepRight.setClampAfter(mSweepLeft);
- mSweepLimit.setClampBefore(mSweepWarning);
- mSweepWarning.setClampAfter(mSweepLimit);
+ mSweepLeft.setValidRangeDynamic(null, mSweepRight, HOUR_IN_MILLIS);
+ mSweepRight.setValidRangeDynamic(mSweepLeft, null, HOUR_IN_MILLIS);
+
+ // TODO: assign these ranges as user changes data axis
+ mSweepWarning.setValidRange(0L, 5 * GB_IN_BYTES);
+ mSweepWarning.setValidRangeDynamic(null, mSweepLimit, MB_IN_BYTES);
+ mSweepLimit.setValidRange(0L, 5 * GB_IN_BYTES);
+ mSweepLimit.setValidRangeDynamic(mSweepWarning, null, MB_IN_BYTES);
mSweepLeft.addOnSweepListener(mSweepListener);
mSweepRight.addOnSweepListener(mSweepListener);
@@ -116,6 +124,7 @@ public class DataUsageChartView extends ChartView {
public void bindNetworkStats(NetworkStatsHistory stats) {
mSeries.bindNetworkStats(stats);
+ mHistory = stats;
updatePrimaryRange();
requestLayout();
}
@@ -197,15 +206,6 @@ public class DataUsageChartView extends ChartView {
}
}
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (!isActivated()) {
- return true;
- } else {
- return super.onInterceptTouchEvent(ev);
- }
- }
-
public long getInspectStart() {
return mSweepLeft.getValue();
}
@@ -222,18 +222,33 @@ public class DataUsageChartView extends ChartView {
return mSweepLimit.getValue();
}
+ private long getStatsStart() {
+ return mHistory != null ? mHistory.getStart() : Long.MIN_VALUE;
+ }
+
+ private long getStatsEnd() {
+ return mHistory != null ? mHistory.getEnd() : Long.MAX_VALUE;
+ }
+
/**
* Set the exact time range that should be displayed, updating how
* {@link ChartNetworkSeriesView} paints. Moves inspection ranges to be the
* last "week" of available data, without triggering listener events.
*/
- public void setVisibleRange(long start, long end, long dataBoundary) {
- mHoriz.setBounds(start, end);
+ public void setVisibleRange(long visibleStart, long visibleEnd) {
+ mHoriz.setBounds(visibleStart, visibleEnd);
+
+ final long validStart = Math.max(visibleStart, getStatsStart());
+ final long validEnd = Math.min(visibleEnd, getStatsEnd());
+
+ // prevent time sweeps from leaving valid data
+ mSweepLeft.setValidRange(validStart, validEnd);
+ mSweepRight.setValidRange(validStart, validEnd);
// default sweeps to last week of data
- final long halfRange = (end + start) / 2;
- final long sweepMax = Math.min(end, dataBoundary);
- final long sweepMin = Math.max(start, (sweepMax - DateUtils.WEEK_IN_MILLIS));
+ final long halfRange = (visibleEnd + visibleStart) / 2;
+ final long sweepMax = validEnd;
+ final long sweepMin = Math.max(visibleStart, (sweepMax - DateUtils.WEEK_IN_MILLIS));
mSweepLeft.setValue(sweepMin);
mSweepRight.setValue(sweepMax);