Merge "Import translations. DO NOT MERGE" into nyc-mr2-dev
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 67798e9..13b8bd6 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -33,6 +33,7 @@
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.Slog;
+import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
@@ -45,6 +46,8 @@
     static final String TAG = "PowerUI";
     static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final long TEMPERATURE_INTERVAL = 30 * DateUtils.SECOND_IN_MILLIS;
+    private static final long TEMPERATURE_LOGGING_INTERVAL = DateUtils.HOUR_IN_MILLIS;
+    private static final int MAX_RECENT_TEMPS = 125; // TEMPERATURE_LOGGING_INTERVAL plus a buffer
 
     private final Handler mHandler = new Handler();
     private final Receiver mReceiver = new Receiver();
@@ -62,7 +65,10 @@
 
     private long mScreenOffTime = -1;
 
-    private float mThrottlingTemp;
+    private float mThresholdTemp;
+    private float[] mRecentTemps = new float[MAX_RECENT_TEMPS];
+    private int mNumTemps;
+    private long mNextLogTime;
 
     public void start() {
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -228,10 +234,10 @@
             return;
         }
 
-        mThrottlingTemp = Settings.Global.getFloat(resolver, Settings.Global.WARNING_TEMPERATURE,
+        mThresholdTemp = Settings.Global.getFloat(resolver, Settings.Global.WARNING_TEMPERATURE,
                 resources.getInteger(R.integer.config_warningTemperature));
 
-        if (mThrottlingTemp < 0f) {
+        if (mThresholdTemp < 0f) {
             // Get the throttling temperature. No need to check if we're not throttling.
             float[] throttlingTemps = mHardwarePropertiesManager.getDeviceTemperatures(
                     HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
@@ -241,41 +247,86 @@
                     || throttlingTemps[0] == HardwarePropertiesManager.UNDEFINED_TEMPERATURE) {
                 return;
             }
-            mThrottlingTemp = throttlingTemps[0];
+            mThresholdTemp = throttlingTemps[0];
         }
+        setNextLogTime();
 
         // We have passed all of the checks, start checking the temp
         updateTemperatureWarning();
     }
 
     private void updateTemperatureWarning() {
-        PhoneStatusBar phoneStatusBar = getComponent(PhoneStatusBar.class);
-        if (phoneStatusBar != null && phoneStatusBar.isDeviceInVrMode()) {
-            // ensure the warning isn't showing, since VR shows its own warning
-            mWarnings.dismissTemperatureWarning();
-        } else {
-            float[] temps = mHardwarePropertiesManager.getDeviceTemperatures(
-                    HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
-                    HardwarePropertiesManager.TEMPERATURE_CURRENT);
-            boolean shouldShowTempWarning = false;
-            for (float temp : temps) {
-                if (temp >= mThrottlingTemp) {
-                    Slog.i(TAG, "currentTemp=" + temp + ", throttlingTemp=" + mThrottlingTemp);
-                    shouldShowTempWarning = true;
-                    break;
-                }
-            }
-            if (shouldShowTempWarning) {
+        float[] temps = mHardwarePropertiesManager.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+                HardwarePropertiesManager.TEMPERATURE_CURRENT);
+        if (temps.length != 0) {
+            float temp = temps[0];
+            mRecentTemps[mNumTemps++] = temp;
+
+            PhoneStatusBar phoneStatusBar = getComponent(PhoneStatusBar.class);
+            if (phoneStatusBar != null && !phoneStatusBar.isDeviceInVrMode()
+                    && temp >= mThresholdTemp) {
+                logAtTemperatureThreshold(temp);
                 mWarnings.showTemperatureWarning();
             } else {
                 mWarnings.dismissTemperatureWarning();
             }
         }
 
-        // TODO: skip this when in VR mode since we already get a callback
+        logTemperatureStats();
+
         mHandler.postDelayed(this::updateTemperatureWarning, TEMPERATURE_INTERVAL);
     }
 
+    private void logAtTemperatureThreshold(float temp) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("currentTemp=").append(temp)
+                .append(",thresholdTemp=").append(mThresholdTemp)
+                .append(",batteryStatus=").append(mBatteryStatus)
+                .append(",recentTemps=");
+        for (int i = 0; i < mNumTemps; i++) {
+            sb.append(mRecentTemps[i]).append(',');
+        }
+        Slog.i(TAG, sb.toString());
+    }
+
+    /**
+     * Calculates and logs min, max, and average
+     * {@link HardwarePropertiesManager#DEVICE_TEMPERATURE_SKIN} over the past
+     * {@link #TEMPERATURE_LOGGING_INTERVAL}.
+     */
+    private void logTemperatureStats() {
+        if (mNextLogTime > System.currentTimeMillis() && mNumTemps != MAX_RECENT_TEMPS) {
+            return;
+        }
+
+        if (mNumTemps > 0) {
+            float sum = mRecentTemps[0], min = mRecentTemps[0], max = mRecentTemps[0];
+            for (int i = 1; i < mNumTemps; i++) {
+                float temp = mRecentTemps[i];
+                sum += temp;
+                if (temp > max) {
+                    max = temp;
+                }
+                if (temp < min) {
+                    min = temp;
+                }
+            }
+
+            float avg = sum / mNumTemps;
+            Slog.i(TAG, "avg=" + avg + ",min=" + min + ",max=" + max);
+            MetricsLogger.histogram(mContext, "device_skin_temp_avg", (int) avg);
+            MetricsLogger.histogram(mContext, "device_skin_temp_min", (int) min);
+            MetricsLogger.histogram(mContext, "device_skin_temp_max", (int) max);
+        }
+        setNextLogTime();
+        mNumTemps = 0;
+    }
+
+    private void setNextLogTime() {
+        mNextLogTime = System.currentTimeMillis() + TEMPERATURE_LOGGING_INTERVAL;
+    }
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.print("mLowBatteryAlertCloseLevel=");
         pw.println(mLowBatteryAlertCloseLevel);
@@ -302,8 +353,10 @@
                 Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0));
         pw.print("bucket: ");
         pw.println(Integer.toString(findBatteryLevelBucket(mBatteryLevel)));
-        pw.print("mThrottlingTemp=");
-        pw.println(Float.toString(mThrottlingTemp));
+        pw.print("mThresholdTemp=");
+        pw.println(Float.toString(mThresholdTemp));
+        pw.print("mNextLogTime=");
+        pw.println(Long.toString(mNextLogTime));
         mWarnings.dump(pw);
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index fd3fa82..7719d5a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1781,7 +1781,10 @@
 
     private void setDeviceOwnerSystemPropertyLocked() {
         // Device owner may still be provisioned, do not set the read-only system property yet.
-        if (mInjector.settingsGlobalGetInt(Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
+        // Wear devices don't set device_provisioned until the device is paired, so allow
+        // device_owner property to be set without that.
+        if (!mIsWatch
+                && mInjector.settingsGlobalGetInt(Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
             return;
         }
         // Still at the first stage of CryptKeeper double bounce, mOwners.hasDeviceOwner is