Merge "Import translations. DO NOT MERGE"
diff --git a/Android.mk b/Android.mk
index 0663e85..52fcfb4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -6,7 +6,9 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := \
+        $(call all-java-files-under, src) \
+        src/com/android/settings/EventLogTags.logtags
 
 LOCAL_PACKAGE_NAME := Settings
 LOCAL_CERTIFICATE := platform
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4d09484..965c1ad 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1221,6 +1221,8 @@
     <string name="wifi_display_status_connected">Connected</string>
     <!-- Wifi Display settings. The status summary for available devices. [CHAR LIMIT=40] -->
     <string name="wifi_display_status_available">Available</string>
+    <!-- Wifi Display settings. The status summary for busy devices. [CHAR LIMIT=40] -->
+    <string name="wifi_display_status_busy">Busy</string>
     <!-- Wifi Display settings. Image description for device details button. This opens the screen to rename, unpair, etc. a single device. -->
     <string name="wifi_display_details">Display settings</string>
 
@@ -3314,10 +3316,14 @@
     <string name="usage_type_phone" product="tablet">Tablet</string>
     <!-- Label for Phone usage time -->
     <string name="usage_type_phone" product="default">Phone</string>
-    <!-- Label for Data sent -->
-    <string name="usage_type_data_send">Data sent</string>
-    <!-- Label for Data received -->
-    <string name="usage_type_data_recv">Data received</string>
+    <!-- Label for mobile network data sent [CHAR LIMIT=32] -->
+    <string name="usage_type_data_send">Mobile data sent</string>
+    <!-- Label for mobile network data received [CHAR LIMIT=32] -->
+    <string name="usage_type_data_recv">Mobile data received</string>
+    <!-- Label for Wi-Fi network data sent [CHAR LIMIT=32] -->
+    <string name="usage_type_data_wifi_send">Wi\u2011Fi data sent</string>
+    <!-- Label for Wi-Fi network data received [CHAR LIMIT=32] -->
+    <string name="usage_type_data_wifi_recv">Wi\u2011Fi data received</string>
     <!-- Label for Audio usage time -->
     <string name="usage_type_audio">Audio</string>
     <!-- Label for Video usage time -->
diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java
index 14671d1..8db5a75 100644
--- a/src/com/android/settings/ChooseLockGeneric.java
+++ b/src/com/android/settings/ChooseLockGeneric.java
@@ -28,6 +28,7 @@
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
 import android.security.KeyStore;
+import android.util.EventLog;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -122,6 +123,9 @@
                 Preference preference) {
             final String key = preference.getKey();
             boolean handled = true;
+
+            EventLog.writeEvent(EventLogTags.LOCK_SCREEN_TYPE, key);
+
             if (KEY_UNLOCK_SET_OFF.equals(key)) {
                 updateUnlockMethodAndFinish(
                         DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, true);
diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/DeviceAdminAdd.java
index 27e7a54..6234038 100644
--- a/src/com/android/settings/DeviceAdminAdd.java
+++ b/src/com/android/settings/DeviceAdminAdd.java
@@ -116,34 +116,38 @@
             return;
         }
 
-        // Make sure the given component name is actually a valid device admin.
-        List<ResolveInfo> avail = getPackageManager().queryBroadcastReceivers(
-                new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
-                PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
-        int count = avail == null ? 0 : avail.size();
-        boolean found = false;
-        for (int i=0; i<count; i++) {
-            ResolveInfo ri = avail.get(i);
-            if (ai.packageName.equals(ri.activityInfo.packageName)
-                    && ai.name.equals(ri.activityInfo.name)) {
-                try {
-                    // We didn't retrieve the meta data for all possible matches, so
-                    // need to use the activity info of this specific one that was retrieved.
-                    ri.activityInfo = ai;
-                    DeviceAdminInfo dpi = new DeviceAdminInfo(this, ri);
-                    found = true;
-                } catch (XmlPullParserException e) {
-                    Log.w(TAG, "Bad " + ri.activityInfo, e);
-                } catch (IOException e) {
-                    Log.w(TAG, "Bad " + ri.activityInfo, e);
+        // When activating, make sure the given component name is actually a valid device admin.
+        // No need to check this when deactivating, because it is safe to deactivate an active
+        // invalid device admin.
+        if (!mDPM.isAdminActive(cn)) {
+            List<ResolveInfo> avail = getPackageManager().queryBroadcastReceivers(
+                    new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
+                    PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
+            int count = avail == null ? 0 : avail.size();
+            boolean found = false;
+            for (int i=0; i<count; i++) {
+                ResolveInfo ri = avail.get(i);
+                if (ai.packageName.equals(ri.activityInfo.packageName)
+                        && ai.name.equals(ri.activityInfo.name)) {
+                    try {
+                        // We didn't retrieve the meta data for all possible matches, so
+                        // need to use the activity info of this specific one that was retrieved.
+                        ri.activityInfo = ai;
+                        DeviceAdminInfo dpi = new DeviceAdminInfo(this, ri);
+                        found = true;
+                    } catch (XmlPullParserException e) {
+                        Log.w(TAG, "Bad " + ri.activityInfo, e);
+                    } catch (IOException e) {
+                        Log.w(TAG, "Bad " + ri.activityInfo, e);
+                    }
+                    break;
                 }
-                break;
             }
-        }
-        if (!found) {
-            Log.w(TAG, "Request to add invalid device admin: " + cn);
-            finish();
-            return;
+            if (!found) {
+                Log.w(TAG, "Request to add invalid device admin: " + cn);
+                finish();
+                return;
+            }
         }
 
         ResolveInfo ri = new ResolveInfo();
diff --git a/src/com/android/settings/EventLogTags.logtags b/src/com/android/settings/EventLogTags.logtags
new file mode 100644
index 0000000..3e87c53
--- /dev/null
+++ b/src/com/android/settings/EventLogTags.logtags
@@ -0,0 +1,6 @@
+# See system/core/logcat/event.logtags for a description of the format of this file.
+
+option java_package com.android.settings
+
+# log the type of screen lock when user sets lock screen
+90200 lock_screen_type (type|3)
diff --git a/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java b/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java
index 61188ec..1992fac 100644
--- a/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java
+++ b/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java
@@ -137,6 +137,8 @@
     public void init() {
         final Context context = getContext();
 
+        removeAll();
+
         final UserInfo currentUser;
         try {
             currentUser = ActivityManagerNative.getDefault().getCurrentUser();
@@ -242,9 +244,6 @@
 
         if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
             mItemAvailable.setTitle(R.string.memory_available_read_only);
-            if (mFormatPreference != null) {
-                removePreference(mFormatPreference);
-            }
         } else {
             mItemAvailable.setTitle(R.string.memory_available);
         }
@@ -269,9 +268,6 @@
             removePreference(mUsageBarPreference);
             removePreference(mItemTotal);
             removePreference(mItemAvailable);
-            if (mFormatPreference != null) {
-                removePreference(mFormatPreference);
-            }
         }
 
         if (mUsbConnected && (UsbManager.USB_FUNCTION_MTP.equals(mUsbFunction) ||
@@ -374,6 +370,7 @@
     }
 
     public void onStorageStateChanged() {
+        init();
         measure();
     }
 
diff --git a/src/com/android/settings/fuelgauge/BatterySipper.java b/src/com/android/settings/fuelgauge/BatterySipper.java
index 9a8e783..d581fb4 100644
--- a/src/com/android/settings/fuelgauge/BatterySipper.java
+++ b/src/com/android/settings/fuelgauge/BatterySipper.java
@@ -49,8 +49,10 @@
     long wifiRunningTime;
     long cpuFgTime;
     long wakeLockTime;
-    long tcpBytesReceived;
-    long tcpBytesSent;
+    long mobileRxBytes;
+    long mobileTxBytes;
+    long wifiRxBytes;
+    long wifiTxBytes;
     double percent;
     double noCoveragePercent;
     String defaultPackageName;
diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
index 8ecc659..945b86b 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
@@ -316,6 +316,8 @@
                 switch (mTypes[i]) {
                     case R.string.usage_type_data_recv:
                     case R.string.usage_type_data_send:
+                    case R.string.usage_type_data_wifi_recv:
+                    case R.string.usage_type_data_wifi_send:
                         final long bytes = (long) (mValues[i]);
                         value = Formatter.formatFileSize(getActivity(), bytes);
                         break;
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 39dc1d6..8307530 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -16,6 +16,11 @@
 
 package com.android.settings.fuelgauge;
 
+import static android.os.BatteryStats.NETWORK_MOBILE_RX_BYTES;
+import static android.os.BatteryStats.NETWORK_MOBILE_TX_BYTES;
+import static android.os.BatteryStats.NETWORK_WIFI_RX_BYTES;
+import static android.os.BatteryStats.NETWORK_WIFI_TX_BYTES;
+
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -24,7 +29,6 @@
 import android.graphics.drawable.Drawable;
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
-import android.net.Uri;
 import android.os.BatteryStats;
 import android.os.BatteryStats.Uid;
 import android.os.Bundle;
@@ -229,8 +233,10 @@
                     R.string.usage_type_wake_lock,
                     R.string.usage_type_gps,
                     R.string.usage_type_wifi_running,
-                    R.string.usage_type_data_send,
                     R.string.usage_type_data_recv,
+                    R.string.usage_type_data_send,
+                    R.string.usage_type_data_wifi_recv,
+                    R.string.usage_type_data_wifi_send,
                     R.string.usage_type_audio,
                     R.string.usage_type_video,
                 };
@@ -240,8 +246,10 @@
                     sipper.wakeLockTime,
                     sipper.gpsTime,
                     sipper.wifiRunningTime,
-                    sipper.tcpBytesSent,
-                    sipper.tcpBytesReceived,
+                    sipper.mobileRxBytes,
+                    sipper.mobileTxBytes,
+                    sipper.wifiRxBytes,
+                    sipper.wifiTxBytes,
                     0,
                     0
                 };
@@ -279,16 +287,20 @@
                     R.string.usage_type_cpu,
                     R.string.usage_type_cpu_foreground,
                     R.string.usage_type_wake_lock,
-                    R.string.usage_type_data_send,
                     R.string.usage_type_data_recv,
+                    R.string.usage_type_data_send,
+                    R.string.usage_type_data_wifi_recv,
+                    R.string.usage_type_data_wifi_send,
                 };
                 values = new double[] {
                     sipper.usageTime,
                     sipper.cpuTime,
                     sipper.cpuFgTime,
                     sipper.wakeLockTime,
-                    sipper.tcpBytesSent,
-                    sipper.tcpBytesReceived,
+                    sipper.mobileRxBytes,
+                    sipper.mobileTxBytes,
+                    sipper.wifiRxBytes,
+                    sipper.wifiTxBytes,
                 };
             } break;
             case BLUETOOTH:
@@ -298,16 +310,20 @@
                     R.string.usage_type_cpu,
                     R.string.usage_type_cpu_foreground,
                     R.string.usage_type_wake_lock,
-                    R.string.usage_type_data_send,
                     R.string.usage_type_data_recv,
+                    R.string.usage_type_data_send,
+                    R.string.usage_type_data_wifi_recv,
+                    R.string.usage_type_data_wifi_send,
                 };
                 values = new double[] {
                     sipper.usageTime,
                     sipper.cpuTime,
                     sipper.cpuFgTime,
                     sipper.wakeLockTime,
-                    sipper.tcpBytesSent,
-                    sipper.tcpBytesReceived,
+                    sipper.mobileRxBytes,
+                    sipper.mobileTxBytes,
+                    sipper.wifiRxBytes,
+                    sipper.wifiTxBytes,
                 };
             } break;
             default:
@@ -445,7 +461,8 @@
         for (int p = 0; p < speedSteps; p++) {
             powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p);
         }
-        final double averageCostPerByte = getAverageDataCost();
+        final double mobilePowerPerByte = getMobilePowerPerByte();
+        final double wifiPowerPerByte = getWifiPowerPerByte();
         long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
         long appWakelockTime = 0;
         BatterySipper osApp = null;
@@ -454,8 +471,8 @@
         final int NU = uidStats.size();
         for (int iu = 0; iu < NU; iu++) {
             Uid u = uidStats.valueAt(iu);
-            double p;
-            double power = 0;
+            double p; // in mAs
+            double power = 0; // in mAs
             double highestDrain = 0;
             String packageWithHighestDrain = null;
             //mUsageList.add(new AppUsage(u.getUid(), new double[] {power}));
@@ -535,12 +552,19 @@
             power += p;
             if (DEBUG && p != 0) Log.i(TAG, String.format("wakelock power=%.2f", p));
             
-            // Add cost of data traffic
-            long tcpBytesReceived = u.getTcpBytesReceived(mStatsType);
-            long tcpBytesSent = u.getTcpBytesSent(mStatsType);
-            p = (tcpBytesReceived+tcpBytesSent) * averageCostPerByte;
+            // Add cost of mobile traffic
+            final long mobileRx = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, mStatsType);
+            final long mobileTx = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, mStatsType);
+            p = (mobileRx + mobileTx) * mobilePowerPerByte;
             power += p;
-            if (DEBUG && p != 0) Log.i(TAG, String.format("tcp power=%.2f", p));
+            if (DEBUG && p != 0) Log.i(TAG, String.format("mobile power=%.2f", p));
+
+            // Add cost of wifi traffic
+            final long wifiRx = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, mStatsType);
+            final long wifiTx = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, mStatsType);
+            p = (wifiRx + wifiTx) * wifiPowerPerByte;
+            power += p;
+            if (DEBUG && p != 0) Log.i(TAG, String.format("wifi power=%.2f", p));
 
             // Add cost of keeping WIFI running.
             long wifiRunningTimeMs = u.getWifiRunningTime(uSecTime, which) / 1000;
@@ -602,8 +626,10 @@
                 app.wifiRunningTime = wifiRunningTimeMs;
                 app.cpuFgTime = cpuFgTime;
                 app.wakeLockTime = wakelockTime;
-                app.tcpBytesReceived = tcpBytesReceived;
-                app.tcpBytesSent = tcpBytesSent;
+                app.mobileRxBytes = mobileRx;
+                app.mobileTxBytes = mobileTx;
+                app.wifiRxBytes = wifiRx;
+                app.wifiTxBytes = wifiTx;
                 if (u.getUid() == Process.WIFI_UID) {
                     mWifiSippers.add(app);
                 } else if (u.getUid() == Process.BLUETOOTH_UID) {
@@ -725,8 +751,10 @@
             bs.wifiRunningTime += wbs.wifiRunningTime;
             bs.cpuFgTime += wbs.cpuFgTime;
             bs.wakeLockTime += wbs.wakeLockTime;
-            bs.tcpBytesReceived += wbs.tcpBytesReceived;
-            bs.tcpBytesSent += wbs.tcpBytesSent;
+            bs.mobileRxBytes += wbs.mobileRxBytes;
+            bs.mobileTxBytes += wbs.mobileTxBytes;
+            bs.wifiRxBytes += wbs.wifiRxBytes;
+            bs.wifiTxBytes += wbs.wifiTxBytes;
         }
     }
 
@@ -796,30 +824,34 @@
         }
     }
 
-    private double getAverageDataCost() {
-        final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system 
+    /**
+     * Return estimated power (in mAs) of sending a byte with the mobile radio.
+     */
+    private double getMobilePowerPerByte() {
         final long MOBILE_BPS = 200000; // TODO: Extract average bit rates from system
-        final double WIFI_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE)
-                / 3600;
         final double MOBILE_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
                 / 3600;
-        final long mobileData = mStats.getMobileTcpBytesReceived(mStatsType) +
-                mStats.getMobileTcpBytesSent(mStatsType);
-        final long wifiData = mStats.getTotalTcpBytesReceived(mStatsType) +
-                mStats.getTotalTcpBytesSent(mStatsType) - mobileData;
+
+        final long mobileRx = mStats.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, mStatsType);
+        final long mobileTx = mStats.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, mStatsType);
+        final long mobileData = mobileRx + mobileTx;
+
         final long radioDataUptimeMs = mStats.getRadioDataUptime() / 1000;
         final long mobileBps = radioDataUptimeMs != 0
                 ? mobileData * 8 * 1000 / radioDataUptimeMs
                 : MOBILE_BPS;
 
-        double mobileCostPerByte = MOBILE_POWER / (mobileBps / 8);
-        double wifiCostPerByte = WIFI_POWER / (WIFI_BPS / 8);
-        if (wifiData + mobileData != 0) {
-            return (mobileCostPerByte * mobileData + wifiCostPerByte * wifiData)
-                    / (mobileData + wifiData);
-        } else {
-            return 0;
-        }
+        return MOBILE_POWER / (mobileBps / 8);
+    }
+
+    /**
+     * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio.
+     */
+    private double getWifiPowerPerByte() {
+        final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system
+        final double WIFI_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE)
+                / 3600;
+        return WIFI_POWER / (WIFI_BPS / 8);
     }
 
     private void processMiscUsage() {
diff --git a/src/com/android/settings/wfd/WifiDisplaySettings.java b/src/com/android/settings/wfd/WifiDisplaySettings.java
index 5b732d6..ca2d254 100755
--- a/src/com/android/settings/wfd/WifiDisplaySettings.java
+++ b/src/com/android/settings/wfd/WifiDisplaySettings.java
@@ -182,7 +182,7 @@
 
             if (display.equals(mWifiDisplayStatus.getActiveDisplay())) {
                 showDisconnectDialog(display);
-            } else {
+            } else if (display.canConnect()){
                 mDisplayManager.connectWifiDisplay(display.getDeviceAddress());
             }
         }
@@ -267,6 +267,17 @@
         } else if (paired && contains(mWifiDisplayStatus.getAvailableDisplays(),
                 d.getDeviceAddress())) {
             p.setSummary(R.string.wifi_display_status_available);
+            for (WifiDisplay display : mWifiDisplayStatus.getAvailableDisplays()) {
+                if (display.getDeviceAddress().equals(d.getDeviceAddress()) &&
+                        !display.canConnect()) {
+                    p.setSummary(R.string.wifi_display_status_busy);
+                    p.setEnabled(false);
+                    break;
+                }
+            }
+        } else if (!paired && !d.canConnect()) {
+            p.setSummary(R.string.wifi_display_status_busy);
+            p.setEnabled(false);
         }
         if (paired) {
             p.setWidgetLayoutResource(R.layout.wifi_display_preference);