diff options
author | Jeff Sharkey <jsharkey@android.com> | 2011-07-27 22:08:05 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-07-27 22:08:05 -0700 |
commit | 18d2b15b80a5926f8a64459f98c955d45029c453 (patch) | |
tree | 1ff3ef75435068afc20de6683e3aa189515e2608 /src | |
parent | a75a5ea80b9651472e9209364987460eb561ec64 (diff) | |
parent | d360e5efaaf4ea5f487a84787210a6c5d26337a8 (diff) | |
download | packages_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.java | 113 | ||||
-rw-r--r-- | src/com/android/settings/widget/ChartSweepView.java | 85 | ||||
-rw-r--r-- | src/com/android/settings/widget/DataUsageChartView.java | 51 |
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); |