Merge "Power widget - track brightness changes."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 504ca90..20df0d6 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -975,7 +975,7 @@
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                android:value="com.android.settings.nfc.ZeroClick" />
+                android:value="com.android.settings.nfc.ShareTap" />
         </activity>
 
         <!-- Accessibility tutorial -->
diff --git a/res/layout/sharetap.xml b/res/layout/sharetap.xml
index fb31d83..bd65df2 100644
--- a/res/layout/sharetap.xml
+++ b/res/layout/sharetap.xml
@@ -48,13 +48,6 @@
                 android:gravity="top"
                 android:text="@string/zeroclick_top"
             />
-            <TextView android:id="@+id/sharetap_safety"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="20dip"
-                android:gravity="top"
-                android:text="@string/zeroclick_safety"
-            />
         </LinearLayout>
 
     </ScrollView>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 821ebd4..c9bfb7f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1106,8 +1106,7 @@
     <!-- Used in the zero-click sharing preferences screen -->
     <string name="zeroclick_label">ShareTap</string>
     <string name="zeroclick_explained">Share content by touching two NFC-enabled devices back to back.</string>
-    <string name="zeroclick_top">The app on the top device\'s screen sends content to the bottom device.</string>
-    <string name="zeroclick_safety">Your data is safe: nothing is shared unless both devices are on and unlocked.</string>
+    <string name="zeroclick_top">The app on the top device\'s screen sends content to the bottom device.\n\nYour data is safe: nothing is shared unless both devices are on and unlocked.\n\nYou can turn this feature off in Settings > More > ShareTap.</string>
     <!-- Wi-Fi Settings --> <skip />
     <!-- Used in the 1st-level settings screen to turn on Wi-Fi -->
     <string name="wifi_quick_toggle_title">Wi-Fi</string>
@@ -3455,6 +3454,8 @@
     <string name="data_usage_disable_4g_limit">Disable 4G data at limit</string>
     <!-- Checkbox label that will disable 2G-3G network data connection when user-defined limit is reached. [CHAR LIMIT=32] -->
     <string name="data_usage_disable_3g_limit">Disable 2G-3G data at limit</string>
+    <!-- Checkbox label that will disable Wi-Fi network data connection when user-defined limit is reached. [CHAR LIMIT=32] -->
+    <string name="data_usage_disable_wifi_limit">Disable Wi-Fi data at limit</string>
 
     <!-- Tab title for showing Wi-Fi data usage. [CHAR LIMIT=10] -->
     <string name="data_usage_tab_wifi">Wi-Fi</string>
@@ -3467,6 +3468,11 @@
     <!-- Tab title for showing 2G and 3G data usage. [CHAR LIMIT=10] -->
     <string name="data_usage_tab_3g">2G-3G</string>
 
+    <!-- Title shown when current operation applies to mobile networks. [CHAR LIMIT=10] -->
+    <string name="data_usage_list_mobile">mobile</string>
+    <!-- Title shown when current operation applies to no networks. [CHAR LIMIT=10] -->
+    <string name="data_usage_list_none">none</string>
+
     <!-- Toggle switch title for enabling all mobile data network connections. [CHAR LIMIT=32] -->
     <string name="data_usage_enable_mobile">Mobile data</string>
     <!-- Toggle switch title for enabling 2G and 3G data network connections. [CHAR LIMIT=32] -->
@@ -3479,9 +3485,9 @@
     <!-- Checkbox label that restricts background data usage of a specific application. [CHAR LIMIT=32] -->
     <string name="data_usage_app_restrict_background">Restrict background data usage</string>
     <!-- Summary message for checkbox that restricts background data usage of a specific application. [CHAR LIMIT=64] -->
-    <string name="data_usage_app_restrict_background_summary">Only allow application background data when using an unlimited network</string>
+    <string name="data_usage_app_restrict_background_summary">Disable background data on networks that you\'ve chosen to limit (<xliff:g id="networks" example="Mobile, Wi-Fi">%1$s</xliff:g>).</string>
     <!-- Title of dialog shown when user restricts background data usage of a specific application. [CHAR LIMIT=48] -->
-    <string name="data_usage_app_restrict_dialog_title">Restricting background data</string>
+    <string name="data_usage_app_restrict_dialog_title">Restrict background data?</string>
     <!-- Body of dialog shown when user restricts background data usage of a specific application. [CHAR LIMIT=NONE] -->
     <string name="data_usage_app_restrict_dialog">This feature may negatively impact applications which depend on background data usage.\n\nMore appropriate data usage controls may be found within this application\'s settings.</string>
 
@@ -3495,16 +3501,12 @@
     <!-- Title of dialog shown before user limits data usage. [CHAR LIMIT=48] -->
     <string name="data_usage_limit_dialog_title">Limiting data usage</string>
     <!-- Body of dialog shown before user limits mobile data usage. [CHAR LIMIT=NONE] -->
-    <string name="data_usage_limit_dialog_mobile">Your mobile data connection will be disabled when the specified limit is reached.\n\nTo avoid overage charges, consider using a reduced limit, as device and carrier accounting methods may vary.</string>
-    <!-- Body of dialog shown before user limits 3G data usage. [CHAR LIMIT=NONE] -->
-    <string name="data_usage_limit_dialog_3g">Your 2G-3G data connection will be disabled when the specified limit is reached.\n\nTo avoid overage charges, consider using a reduced limit, as device and carrier accounting methods may vary.</string>
-    <!-- Body of dialog shown before user limits 4G data usage. [CHAR LIMIT=NONE] -->
-    <string name="data_usage_limit_dialog_4g">Your 4G data connection will be disabled when the specified limit is reached.\n\nTo avoid overage charges, consider using a reduced limit, as device and carrier accounting methods may vary.</string>
+    <string name="data_usage_limit_dialog">Your <xliff:g id="networks" example="mobile">%1$s</xliff:g> data connection will be disabled when the specified limit is reached.\n\nTo avoid overage charges, consider using a reduced limit, as device and carrier accounting methods may vary.</string>
 
     <!-- Title of dialog shown before user restricts background data usage. [CHAR LIMIT=48] -->
-    <string name="data_usage_restrict_background_title">Restricting background data</string>
+    <string name="data_usage_restrict_background_title">Restrict background data?</string>
     <!-- Body of dialog shown before user restricts background data usage. [CHAR LIMIT=NONE] -->
-    <string name="data_usage_restrict_background">This feature will disable auto-sync and may negatively impact applications which depend on background data usage.</string>
+    <string name="data_usage_restrict_background">If you restrict background data, some apps and services won\'t work on networks that you\'ve chosen to limit.\n\nCurrently limited networks: <xliff:g id="networks" example="Mobile, Wi-Fi">%1$s</xliff:g></string>
 
     <!-- Label displaying current network data usage warning threshold. [CHAR LIMIT=18] -->
     <string name="data_usage_sweep_warning"><font size="21"><xliff:g id="number" example="128">^1</xliff:g></font> <font size="9"><xliff:g id="unit" example="KB">^2</xliff:g></font>\n<font size="12">warning</font></string>
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java
index a95ab3f..b99264f 100644
--- a/src/com/android/settings/DataUsageSummary.java
+++ b/src/com/android/settings/DataUsageSummary.java
@@ -322,9 +322,6 @@
             mAppRestrict = new CheckBox(inflater.getContext());
             mAppRestrict.setClickable(false);
             mAppRestrictView = inflatePreference(inflater, mAppSwitches, mAppRestrict);
-            setPreferenceTitle(mAppRestrictView, R.string.data_usage_app_restrict_background);
-            setPreferenceSummary(
-                    mAppRestrictView, R.string.data_usage_app_restrict_background_summary);
             mAppRestrictView.setOnClickListener(mAppRestrictListener);
             mAppSwitches.addView(mAppRestrictView);
         }
@@ -588,22 +585,8 @@
 
         if (LOGD) Log.d(TAG, "updateBody() with currentTab=" + currentTab);
 
-        if (TAB_WIFI.equals(currentTab)) {
-            // wifi doesn't have any controls
-            mDataEnabledView.setVisibility(View.GONE);
-            mDisableAtLimitView.setVisibility(View.GONE);
-            mTemplate = buildTemplateWifi();
-
-        } else if (TAB_ETHERNET.equals(currentTab)) {
-            // ethernet doesn't have any controls
-            mDataEnabledView.setVisibility(View.GONE);
-            mDisableAtLimitView.setVisibility(View.GONE);
-            mTemplate = buildTemplateEthernet();
-
-        } else {
-            mDataEnabledView.setVisibility(View.VISIBLE);
-            mDisableAtLimitView.setVisibility(View.VISIBLE);
-        }
+        mDataEnabledView.setVisibility(View.VISIBLE);
+        mDisableAtLimitView.setVisibility(View.VISIBLE);
 
         if (TAB_MOBILE.equals(currentTab)) {
             setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_mobile);
@@ -622,6 +605,20 @@
             setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_4g_limit);
             // TODO: bind mDataEnabled to 4G radio state
             mTemplate = buildTemplateMobile4g(getActiveSubscriberId(context));
+
+        } else if (TAB_WIFI.equals(currentTab)) {
+            mDataEnabledView.setVisibility(View.GONE);
+            setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_wifi_limit);
+            mTemplate = buildTemplateWifi();
+
+        } else if (TAB_ETHERNET.equals(currentTab)) {
+            // ethernet doesn't have any controls
+            mDataEnabledView.setVisibility(View.GONE);
+            mDisableAtLimitView.setVisibility(View.GONE);
+            mTemplate = buildTemplateEthernet();
+
+        } else {
+            throw new IllegalStateException("unknown tab: " + currentTab);
         }
 
         try {
@@ -731,6 +728,11 @@
 
         if (NetworkPolicyManager.isUidValidForPolicy(context, mUid) && !getRestrictBackground()
                 && isBandwidthControlEnabled()) {
+            setPreferenceTitle(mAppRestrictView, R.string.data_usage_app_restrict_background);
+            setPreferenceSummary(mAppRestrictView,
+                    getString(R.string.data_usage_app_restrict_background_summary,
+                            buildLimitedNetworksList()));
+
             mAppRestrictView.setVisibility(View.VISIBLE);
             mAppRestrict.setChecked(getAppRestrictBackground());
 
@@ -845,7 +847,7 @@
             }
         }
 
-        final NetworkPolicy policy = mPolicyEditor.getPolicy(mTemplate);
+        final NetworkPolicy policy = mPolicyEditor.getPolicy(mTemplate, true);
         if (isNetworkPolicyModifiable()) {
             mDisableAtLimitView.setVisibility(View.VISIBLE);
             mDisableAtLimit.setChecked(policy != null && policy.limitBytes != LIMIT_DISABLED);
@@ -1363,41 +1365,57 @@
      * {@link NetworkPolicy#limitBytes}.
      */
     public static class ConfirmLimitFragment extends DialogFragment {
-        private static final String EXTRA_MESSAGE_ID = "messageId";
+        private static final String EXTRA_MESSAGE = "message";
         private static final String EXTRA_LIMIT_BYTES = "limitBytes";
 
         public static void show(DataUsageSummary parent) {
-            final Bundle args = new Bundle();
+            final Resources res = parent.getResources();
+
+            final CharSequence message;
+            final long limitBytes;
 
             // TODO: customize default limits based on network template
             final String currentTab = parent.mCurrentTab;
             if (TAB_3G.equals(currentTab)) {
-                args.putInt(EXTRA_MESSAGE_ID, R.string.data_usage_limit_dialog_3g);
-                args.putLong(EXTRA_LIMIT_BYTES, 5 * GB_IN_BYTES);
+                message = buildDialogMessage(res, R.string.data_usage_tab_3g);
+                limitBytes = 5 * GB_IN_BYTES;
             } else if (TAB_4G.equals(currentTab)) {
-                args.putInt(EXTRA_MESSAGE_ID, R.string.data_usage_limit_dialog_4g);
-                args.putLong(EXTRA_LIMIT_BYTES, 5 * GB_IN_BYTES);
+                message = buildDialogMessage(res, R.string.data_usage_tab_4g);
+                limitBytes = 5 * GB_IN_BYTES;
             } else if (TAB_MOBILE.equals(currentTab)) {
-                args.putInt(EXTRA_MESSAGE_ID, R.string.data_usage_limit_dialog_mobile);
-                args.putLong(EXTRA_LIMIT_BYTES, 5 * GB_IN_BYTES);
+                message = buildDialogMessage(res, R.string.data_usage_list_mobile);
+                limitBytes = 5 * GB_IN_BYTES;
+            } else if (TAB_WIFI.equals(currentTab)) {
+                message = buildDialogMessage(res, R.string.data_usage_tab_wifi);
+                limitBytes = 5 * GB_IN_BYTES;
+            } else {
+                throw new IllegalArgumentException("unknown current tab: " + currentTab);
             }
 
+            final Bundle args = new Bundle();
+            args.putCharSequence(EXTRA_MESSAGE, message);
+            args.putLong(EXTRA_LIMIT_BYTES, limitBytes);
+
             final ConfirmLimitFragment dialog = new ConfirmLimitFragment();
             dialog.setArguments(args);
             dialog.setTargetFragment(parent, 0);
             dialog.show(parent.getFragmentManager(), TAG_CONFIRM_LIMIT);
         }
 
+        private static CharSequence buildDialogMessage(Resources res, int networkResId) {
+            return res.getString(R.string.data_usage_limit_dialog, res.getString(networkResId));
+        }
+
         @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             final Context context = getActivity();
 
-            final int messageId = getArguments().getInt(EXTRA_MESSAGE_ID);
+            final CharSequence message = getArguments().getCharSequence(EXTRA_MESSAGE);
             final long limitBytes = getArguments().getLong(EXTRA_LIMIT_BYTES);
 
             final AlertDialog.Builder builder = new AlertDialog.Builder(context);
             builder.setTitle(R.string.data_usage_limit_dialog_title);
-            builder.setMessage(messageId);
+            builder.setMessage(message);
 
             builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int which) {
@@ -1419,7 +1437,7 @@
         private static final String EXTRA_CYCLE_DAY = "cycleDay";
 
         public static void show(DataUsageSummary parent) {
-            final NetworkPolicy policy = parent.mPolicyEditor.getPolicy(parent.mTemplate);
+            final NetworkPolicy policy = parent.mPolicyEditor.getPolicy(parent.mTemplate, false);
             final Bundle args = new Bundle();
             args.putInt(CycleEditorFragment.EXTRA_CYCLE_DAY, policy.cycleDay);
 
@@ -1470,8 +1488,6 @@
      */
     public static class ConfirmDataRoamingFragment extends DialogFragment {
         public static void show(DataUsageSummary parent) {
-            final Bundle args = new Bundle();
-
             final ConfirmDataRoamingFragment dialog = new ConfirmDataRoamingFragment();
             dialog.setTargetFragment(parent, 0);
             dialog.show(parent.getFragmentManager(), TAG_CONFIRM_ROAMING);
@@ -1505,8 +1521,6 @@
      */
     public static class ConfirmRestrictFragment extends DialogFragment {
         public static void show(DataUsageSummary parent) {
-            final Bundle args = new Bundle();
-
             final ConfirmRestrictFragment dialog = new ConfirmRestrictFragment();
             dialog.setTargetFragment(parent, 0);
             dialog.show(parent.getFragmentManager(), TAG_CONFIRM_RESTRICT);
@@ -1518,7 +1532,13 @@
 
             final AlertDialog.Builder builder = new AlertDialog.Builder(context);
             builder.setTitle(R.string.data_usage_restrict_background_title);
-            builder.setMessage(R.string.data_usage_restrict_background);
+
+            final DataUsageSummary target = (DataUsageSummary) getTargetFragment();
+            if (target != null) {
+                final CharSequence limitedNetworks = target.buildLimitedNetworksList();
+                builder.setMessage(
+                        getString(R.string.data_usage_restrict_background, limitedNetworks));
+            }
 
             builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int which) {
@@ -1732,6 +1752,40 @@
     }
 
     /**
+     * Build string describing currently limited networks, which defines when
+     * background data is restricted.
+     */
+    private CharSequence buildLimitedNetworksList() {
+        final Context context = getActivity();
+        final String subscriberId = getActiveSubscriberId(context);
+
+        // build combined list of all limited networks
+        final ArrayList<CharSequence> limited = Lists.newArrayList();
+        if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobileAll(subscriberId))) {
+            limited.add(getText(R.string.data_usage_list_mobile));
+        }
+        if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobile3gLower(subscriberId))) {
+            limited.add(getText(R.string.data_usage_tab_3g));
+        }
+        if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobile4g(subscriberId))) {
+            limited.add(getText(R.string.data_usage_tab_4g));
+        }
+        if (mPolicyEditor.hasLimitedPolicy(buildTemplateWifi())) {
+            limited.add(getText(R.string.data_usage_tab_wifi));
+        }
+        if (mPolicyEditor.hasLimitedPolicy(buildTemplateEthernet())) {
+            limited.add(getText(R.string.data_usage_tab_ethernet));
+        }
+
+        // handle case where no networks limited
+        if (limited.isEmpty()) {
+            limited.add(getText(R.string.data_usage_list_none));
+        }
+
+        return TextUtils.join(limited);
+    }
+
+    /**
      * Set {@link android.R.id#title} for a preference view inflated with
      * {@link #inflatePreference(LayoutInflater, ViewGroup, View)}.
      */
@@ -1744,9 +1798,9 @@
      * Set {@link android.R.id#summary} for a preference view inflated with
      * {@link #inflatePreference(LayoutInflater, ViewGroup, View)}.
      */
-    private static void setPreferenceSummary(View parent, int resId) {
+    private static void setPreferenceSummary(View parent, CharSequence string) {
         final TextView summary = (TextView) parent.findViewById(android.R.id.summary);
         summary.setVisibility(View.VISIBLE);
-        summary.setText(resId);
+        summary.setText(string);
     }
 }
diff --git a/src/com/android/settings/net/NetworkPolicyEditor.java b/src/com/android/settings/net/NetworkPolicyEditor.java
index 81cf78e..723c5cc 100644
--- a/src/com/android/settings/net/NetworkPolicyEditor.java
+++ b/src/com/android/settings/net/NetworkPolicyEditor.java
@@ -31,6 +31,7 @@
 import android.net.NetworkTemplate;
 import android.os.AsyncTask;
 import android.os.RemoteException;
+import android.text.format.Time;
 
 import com.android.internal.util.Objects;
 import com.google.android.collect.Lists;
@@ -91,31 +92,53 @@
         }
     }
 
-    public NetworkPolicy getPolicy(NetworkTemplate template) {
+    public boolean hasLimitedPolicy(NetworkTemplate template) {
+        final NetworkPolicy policy = getPolicy(template, false);
+        return policy != null && policy.limitBytes != LIMIT_DISABLED;
+    }
+
+    public NetworkPolicy getPolicy(NetworkTemplate template, boolean createDefault) {
         for (NetworkPolicy policy : mPolicies) {
             if (policy.template.equals(template)) {
                 return policy;
             }
         }
-        return null;
+
+        if (createDefault) {
+            final NetworkPolicy policy = buildDefaultPolicy(template);
+            mPolicies.add(policy);
+            return policy;
+        } else {
+            return null;
+        }
+    }
+
+    private static NetworkPolicy buildDefaultPolicy(NetworkTemplate template) {
+        // TODO: move this into framework to share with NetworkPolicyManagerService
+        final Time time = new Time();
+        time.setToNow();
+        final int cycleDay = time.monthDay;
+
+        return new NetworkPolicy(
+                template, cycleDay, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER);
     }
 
     public void setPolicyCycleDay(NetworkTemplate template, int cycleDay) {
-        final NetworkPolicy policy = getPolicy(template);
+        final NetworkPolicy policy = getPolicy(template, true);
         policy.cycleDay = cycleDay;
         policy.lastSnooze = SNOOZE_NEVER;
         writeAsync();
     }
 
     public void setPolicyWarningBytes(NetworkTemplate template, long warningBytes) {
-        final NetworkPolicy policy = getPolicy(template);
+        final NetworkPolicy policy = getPolicy(template, true);
         policy.warningBytes = warningBytes;
         policy.lastSnooze = SNOOZE_NEVER;
         writeAsync();
     }
 
     public void setPolicyLimitBytes(NetworkTemplate template, long limitBytes) {
-        final NetworkPolicy policy = getPolicy(template);
+        final NetworkPolicy policy = getPolicy(template, true);
         policy.limitBytes = limitBytes;
         policy.lastSnooze = SNOOZE_NEVER;
         writeAsync();
@@ -153,8 +176,8 @@
 
         } else if (beforeSplit && !split) {
             // combine, picking most restrictive policy
-            final NetworkPolicy policy3g = getPolicy(template3g);
-            final NetworkPolicy policy4g = getPolicy(template4g);
+            final NetworkPolicy policy3g = getPolicy(template3g, false);
+            final NetworkPolicy policy4g = getPolicy(template4g, false);
 
             final NetworkPolicy restrictive = policy3g.compareTo(policy4g) < 0 ? policy3g
                     : policy4g;
@@ -167,7 +190,7 @@
 
         } else if (!beforeSplit && split) {
             // duplicate existing policy into two rules
-            final NetworkPolicy policyAll = getPolicy(templateAll);
+            final NetworkPolicy policyAll = getPolicy(templateAll, false);
             mPolicies.remove(policyAll);
             mPolicies.add(
                     new NetworkPolicy(template3g, policyAll.cycleDay, policyAll.warningBytes,
@@ -179,5 +202,4 @@
 
         }
     }
-
 }
diff --git a/src/com/android/settings/widget/ChartGridView.java b/src/com/android/settings/widget/ChartGridView.java
index c2702e4..b930c62 100644
--- a/src/com/android/settings/widget/ChartGridView.java
+++ b/src/com/android/settings/widget/ChartGridView.java
@@ -116,7 +116,7 @@
         mBorder.setBounds(0, 0, width, height);
         mBorder.draw(canvas);
 
-        final int padding = mLayoutStart.getHeight() / 8;
+        final int padding = mLayoutStart != null ? mLayoutStart.getHeight() / 8 : 0;
 
         final Layout start = mLayoutStart;
         if (start != null) {