Change default temp threshold to use shutdown temp

Base the temp threshold to be based on the shutdown temp lowered
by some amount to ensure the warning can be seen before a shutdown.

Test: runtest systemui
Change-Id: I033a776e874d76018592954932ed5127e1b228ae
Fixes: 62845934
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 30b1692..a077fdb 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -328,9 +328,13 @@
     <integer name="config_showTemperatureWarning">0</integer>
 
     <!-- Temp at which to show a warning notification if config_showTemperatureWarning is true.
-         If < 0, uses the value from HardwarePropertiesManager#getDeviceTemperatures. -->
+         If < 0, uses the value from
+         HardwarePropertiesManager#getDeviceTemperatures - config_warningTemperatureTolerance. -->
     <integer name="config_warningTemperature">-1</integer>
 
+    <!-- Fudge factor for how much below the shutdown temp to show the warning. -->
+    <integer name="config_warningTemperatureTolerance">2</integer>
+
     <!-- Accessibility actions -->
     <item type="id" name="action_split_task_to_left" />
     <item type="id" name="action_split_task_to_right" />
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 9c1cb4e..ecc2111 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -39,6 +39,8 @@
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.PluginManagerImpl;
 import com.android.systemui.plugins.VolumeDialogController;
+import com.android.systemui.power.PowerNotificationWarnings;
+import com.android.systemui.power.PowerUI;
 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
 import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
@@ -296,6 +298,8 @@
         mProviders.put(PluginActivityManager.class,
                 () -> new PluginActivityManager(mContext, getDependency(PluginManager.class)));
 
+        mProviders.put(PowerUI.WarningsUI.class, () -> new PowerNotificationWarnings(mContext));
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 6b3daa3..b007f92 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -104,10 +104,9 @@
     private SystemUIDialog mHighTempDialog;
     private SystemUIDialog mThermalShutdownDialog;
 
-    public PowerNotificationWarnings(Context context, NotificationManager notificationManager,
-            StatusBar statusBar) {
+    public PowerNotificationWarnings(Context context) {
         mContext = context;
-        mNoMan = notificationManager;
+        mNoMan = mContext.getSystemService(NotificationManager.class);
         mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mReceiver.init();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index a913999..beb7712 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.power;
 
-import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -33,14 +32,17 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.phone.StatusBar;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -84,10 +86,7 @@
         mHardwarePropertiesManager = (HardwarePropertiesManager)
                 mContext.getSystemService(Context.HARDWARE_PROPERTIES_SERVICE);
         mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
-        mWarnings = new PowerNotificationWarnings(
-                mContext,
-                (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE),
-                getComponent(StatusBar.class));
+        mWarnings = Dependency.get(WarningsUI.class);
         mLastConfiguration.setTo(mContext.getResources().getConfiguration());
 
         ContentObserver obs = new ContentObserver(mHandler) {
@@ -266,13 +265,14 @@
             // Get the throttling temperature. No need to check if we're not throttling.
             float[] throttlingTemps = mHardwarePropertiesManager.getDeviceTemperatures(
                     HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
-                    HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+                    HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
             if (throttlingTemps == null
                     || throttlingTemps.length == 0
                     || throttlingTemps[0] == HardwarePropertiesManager.UNDEFINED_TEMPERATURE) {
                 return;
             }
-            mThresholdTemp = throttlingTemps[0];
+            mThresholdTemp = throttlingTemps[0] -
+                    resources.getInteger(R.integer.config_warningTemperatureTolerance);
         }
 
         setNextLogTime();
@@ -293,7 +293,8 @@
         }
     }
 
-    private void updateTemperatureWarning() {
+    @VisibleForTesting
+    protected void updateTemperatureWarning() {
         float[] temps = mHardwarePropertiesManager.getDeviceTemperatures(
                 HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
                 HardwarePropertiesManager.TEMPERATURE_CURRENT);
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 03f3c56..adb3baf 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -41,6 +41,7 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.TRUST_LISTENER" />
     <uses-permission android:name="android.permission.USE_FINGERPRINT" />
+    <uses-permission android:name="android.permission.DEVICE_POWER" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
index eb59a34..1b74ebb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
@@ -51,8 +51,8 @@
     @Before
     public void setUp() throws Exception {
         // Test Instance.
-        mPowerNotificationWarnings = new PowerNotificationWarnings(
-                mContext, mMockNotificationManager, null);
+        mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager);
+        mPowerNotificationWarnings = new PowerNotificationWarnings(mContext);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
new file mode 100644
index 0000000..e4734a4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.power;
+
+import static android.os.HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN;
+import static android.os.HardwarePropertiesManager.TEMPERATURE_CURRENT;
+import static android.os.HardwarePropertiesManager.TEMPERATURE_SHUTDOWN;
+import static android.provider.Settings.Global.SHOW_TEMPERATURE_WARNING;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.HardwarePropertiesManager;
+import android.provider.Settings;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.testing.TestableResources;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.power.PowerUI.WarningsUI;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class PowerUITest extends SysuiTestCase {
+
+    private HardwarePropertiesManager mHardProps;
+    private WarningsUI mMockWarnings;
+    private PowerUI mPowerUI;
+
+    @Before
+    public void setup() {
+        mMockWarnings = mDependency.injectMockDependency(WarningsUI.class);
+        mHardProps = mock(HardwarePropertiesManager.class);
+        mContext.putComponent(StatusBar.class, mock(StatusBar.class));
+        mContext.addMockSystemService(Context.HARDWARE_PROPERTIES_SERVICE, mHardProps);
+
+        createPowerUi();
+    }
+
+    @Test
+    public void testNoConfig_NoWarnings() {
+        setOverThreshold();
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 0);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings, never()).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testConfig_NoWarnings() {
+        setUnderThreshold();
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 1);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings, never()).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testConfig_Warnings() {
+        setOverThreshold();
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 1);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testSettingOverrideConfig() {
+        setOverThreshold();
+        Settings.Global.putInt(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, 1);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 0);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testShutdownBasedThreshold() {
+        int tolerance = 2;
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 1);
+        resources.addOverride(R.integer.config_warningTemperature, -1);
+        resources.addOverride(R.integer.config_warningTemperatureTolerance, tolerance);
+        when(mHardProps.getDeviceTemperatures(DEVICE_TEMPERATURE_SKIN, TEMPERATURE_SHUTDOWN))
+                .thenReturn(new float[] { 55 + tolerance });
+
+        setCurrentTemp(54); // Below threshold.
+        mPowerUI.start();
+        verify(mMockWarnings, never()).showHighTemperatureWarning();
+
+        setCurrentTemp(56); // Above threshold.
+        mPowerUI.updateTemperatureWarning();
+        verify(mMockWarnings).showHighTemperatureWarning();
+    }
+
+    private void setCurrentTemp(float temp) {
+        when(mHardProps.getDeviceTemperatures(DEVICE_TEMPERATURE_SKIN, TEMPERATURE_CURRENT))
+                .thenReturn(new float[] { temp });
+    }
+
+    private void setOverThreshold() {
+        setCurrentTemp(50000);
+    }
+
+    private void setUnderThreshold() {
+        setCurrentTemp(5);
+    }
+
+    private void createPowerUi() {
+        mPowerUI = new PowerUI();
+        mPowerUI.mContext = mContext;
+        mPowerUI.mComponents = mContext.getComponents();
+    }
+}