Data usage app labels, protect system, hide empty.
Derive better labels from PackageManager, including for sharedUid
case. Disable "App settings" button when no ResolveInfo found, and
hide "Restrict" checkbox for system UIDs. Also hide apps with 0
bytes usage.
Change-Id: I4b0a66f6912c02c56bfcbcb5b46f3ae2ba0df504
diff --git a/src/com/android/settings/DataUsageAppDetail.java b/src/com/android/settings/DataUsageAppDetail.java
index 4e929ad..cee54ee 100644
--- a/src/com/android/settings/DataUsageAppDetail.java
+++ b/src/com/android/settings/DataUsageAppDetail.java
@@ -32,6 +32,7 @@
import android.graphics.Color;
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
+import android.net.NetworkPolicyManager;
import android.net.NetworkStatsHistory;
import android.os.Bundle;
import android.os.RemoteException;
@@ -58,6 +59,7 @@
private static final boolean LOGD = true;
private int mUid;
+ private Intent mAppSettingsIntent;
private static final String TAG_CONFIRM_RESTRICT = "confirmRestrict";
@@ -127,23 +129,38 @@
public void onResume() {
super.onResume();
- final Context context = getActivity();
-
- mUid = getArguments().getInt(Intent.EXTRA_UID);
- mTitle.setText(context.getPackageManager().getNameForUid(mUid));
-
updateBody();
}
private void updateBody() {
+ final PackageManager pm = getActivity().getPackageManager();
+
+ mUid = getArguments().getInt(Intent.EXTRA_UID);
+ mTitle.setText(pm.getNameForUid(mUid));
+
+ // enable settings button when package provides it
+ // TODO: target torwards entire UID instead of just first package
+ final String[] packageNames = pm.getPackagesForUid(mUid);
+ if (packageNames != null && packageNames.length > 0) {
+ mAppSettingsIntent = new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE);
+ mAppSettingsIntent.setPackage(packageNames[0]);
+ mAppSettingsIntent.addCategory(Intent.CATEGORY_DEFAULT);
+
+ final boolean matchFound = pm.resolveActivity(mAppSettingsIntent, 0) != null;
+ mAppSettings.setEnabled(matchFound);
+
+ } else {
+ mAppSettingsIntent = null;
+ mAppSettings.setEnabled(false);
+ }
+
try {
// load stats for current uid and template
// TODO: read template from extras
- mUidPolicy = mPolicyService.getUidPolicy(mUid);
mHistory = mStatsService.getHistoryForUid(mUid, TEMPLATE_MOBILE_ALL);
} catch (RemoteException e) {
- // since we can't do much without policy or history, and we don't
- // want to leave with half-baked UI, we bail hard.
+ // since we can't do much without history, and we don't want to
+ // leave with half-baked UI, we bail hard.
throw new RuntimeException("problem reading network stats", e);
}
@@ -155,12 +172,28 @@
mChart.setVisibleRange(bounds[0], bounds[1] + DateUtils.WEEK_IN_MILLIS, bounds[1]);
updateDetailData();
- // update policy checkbox
- final boolean restrictBackground = (mUidPolicy & POLICY_REJECT_PAID_BACKGROUND) != 0;
- mRestrictBackground.setChecked(restrictBackground);
+ final Context context = getActivity();
+ if (NetworkPolicyManager.isUidValidForPolicy(context, mUid)) {
+ mRestrictBackgroundView.setVisibility(View.VISIBLE);
- // kick preference views so they rebind from changes above
- refreshPreferenceViews();
+ final int uidPolicy;
+ try {
+ uidPolicy = mPolicyService.getUidPolicy(mUid);
+ } catch (RemoteException e) {
+ // since we can't do much without policy, we bail hard.
+ throw new RuntimeException("problem reading network policy", e);
+ }
+
+ // update policy checkbox
+ final boolean restrictBackground = (mUidPolicy & POLICY_REJECT_PAID_BACKGROUND) != 0;
+ mRestrictBackground.setChecked(restrictBackground);
+
+ // kick preference views so they rebind from changes above
+ refreshPreferenceViews();
+
+ } else {
+ mRestrictBackgroundView.setVisibility(View.GONE);
+ }
}
private void updateDetailData() {
@@ -215,12 +248,7 @@
/** {@inheritDoc} */
public void onClick(View v) {
// TODO: target torwards entire UID instead of just first package
- final PackageManager pm = getActivity().getPackageManager();
- final String packageName = pm.getPackagesForUid(mUid)[0];
-
- final Intent intent = new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE);
- intent.setPackage(packageName);
- startActivity(intent);
+ startActivity(mAppSettingsIntent);
}
};
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java
index beb3ed4f..8849f2d 100644
--- a/src/com/android/settings/DataUsageSummary.java
+++ b/src/com/android/settings/DataUsageSummary.java
@@ -32,7 +32,10 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
import android.net.NetworkPolicy;
@@ -46,6 +49,7 @@
import android.preference.PreferenceActivity;
import android.preference.SwitchPreference;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.format.Formatter;
import android.text.format.Time;
@@ -537,7 +541,10 @@
mCycleSpinner.setSelection(0);
} else {
- if (LOGD) Log.d(TAG, "showing cycle " + cycle);
+ if (LOGD) {
+ Log.d(TAG, "showing cycle " + cycle + ", start=" + cycle.start + ", end="
+ + cycle.end + "]");
+ }
// update chart to show selected cycle, and update detail data
// to match updated sweep bounds.
@@ -670,10 +677,13 @@
mItems.clear();
for (int i = 0; i < stats.size; i++) {
- final AppUsageItem item = new AppUsageItem();
- item.uid = stats.uid[i];
- item.total = stats.rx[i] + stats.tx[i];
- mItems.add(item);
+ final long total = stats.rx[i] + stats.tx[i];
+ if (total > 0) {
+ final AppUsageItem item = new AppUsageItem();
+ item.uid = stats.uid[i];
+ item.total = total;
+ mItems.add(item);
+ }
}
Collections.sort(mItems);
@@ -709,7 +719,7 @@
final TextView text2 = (TextView) convertView.findViewById(android.R.id.text2);
final AppUsageItem item = mItems.get(position);
- text1.setText(pm.getNameForUid(item.uid));
+ text1.setText(resolveLabelForUid(pm, item.uid));
text2.setText(Formatter.formatFileSize(context, item.total));
return convertView;
@@ -829,4 +839,36 @@
}
}
+ /**
+ * Resolve best descriptive label for the given UID.
+ */
+ public static CharSequence resolveLabelForUid(PackageManager pm, int uid) {
+ final String[] packageNames = pm.getPackagesForUid(uid);
+ final int length = packageNames != null ? packageNames.length : 0;
+
+ CharSequence label = pm.getNameForUid(uid);
+ try {
+ if (length == 1) {
+ final ApplicationInfo info = pm.getApplicationInfo(packageNames[0], 0);
+ label = info.loadLabel(pm);
+ } else if (length > 1) {
+ for (String packageName : packageNames) {
+ final PackageInfo info = pm.getPackageInfo(packageName, 0);
+ if (info.sharedUserLabel != 0) {
+ label = pm.getText(packageName, info.sharedUserLabel, info.applicationInfo);
+ if (!TextUtils.isEmpty(label)) {
+ break;
+ }
+ }
+ }
+ }
+ } catch (NameNotFoundException e) {
+ }
+
+ if (TextUtils.isEmpty(label)) {
+ label = Integer.toString(uid);
+ }
+ return label;
+ }
+
}
diff --git a/src/com/android/settings/widget/ChartNetworkSeriesView.java b/src/com/android/settings/widget/ChartNetworkSeriesView.java
index 5fc79dd..780ca46 100644
--- a/src/com/android/settings/widget/ChartNetworkSeriesView.java
+++ b/src/com/android/settings/widget/ChartNetworkSeriesView.java
@@ -157,7 +157,8 @@
if (LOGD) {
final RectF bounds = new RectF();
mPathFill.computeBounds(bounds, true);
- Log.d(TAG, "onLayout() rendered with bounds=" + bounds.toString());
+ Log.d(TAG, "onLayout() rendered with bounds=" + bounds.toString() + " and totalData="
+ + totalData);
}
// drop to bottom of graph from current location