Keep screen on when in car mode and the device is powered.

BUG: 2477103

Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 90a0e58..71826ff 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -38,10 +38,12 @@
 import android.location.Location;
 import android.location.LocationListener;
 import android.location.LocationManager;
+import android.os.BatteryManager;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.text.format.DateUtils;
@@ -80,6 +82,9 @@
     
     private int mNightMode = UiModeManager.MODE_NIGHT_NO;
     private boolean mCarModeEnabled = false;
+    private boolean mCharging = false;
+    private final boolean mCarModeKeepsScreenOn;
+    private final boolean mDeskModeKeepsScreenOn;
 
     private boolean mComputedNightMode;
     private int mCurUiMode = 0;
@@ -96,6 +101,7 @@
     private Location mLocation;
     private StatusBarManager mStatusBarManager;
     private KeyguardManager.KeyguardLock mKeyguardLock;
+    private final PowerManager.WakeLock mWakeLock;
 
     // The broadcast receiver which receives the result of the ordered broadcast sent when
     // the dock state changes. The original ordered broadcast is sent with an initial result
@@ -150,6 +156,18 @@
         }
     };
 
+    private final BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mCharging = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
+            synchronized (mLock) {
+                if (mSystemReady) {
+                    updateLocked();
+                }
+            }
+        }
+    };
+
     // A LocationListener to initialize the network location provider. The location updates
     // are handled through the passive location provider.
     private final LocationListener mEmptyLocationListener =  new LocationListener() {
@@ -237,8 +255,18 @@
                 new IntentFilter(ACTION_UPDATE_NIGHT_MODE));
         mContext.registerReceiver(mDockModeReceiver,
                 new IntentFilter(Intent.ACTION_DOCK_EVENT));
+        mContext.registerReceiver(mBatteryReceiver,
+                new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+
+        PowerManager powerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
 
         mConfiguration.setToDefaults();
+
+        mCarModeKeepsScreenOn = (context.getResources().getInteger(
+                com.android.internal.R.integer.config_carDockKeepsScreenOn) == 1);
+        mDeskModeKeepsScreenOn = (context.getResources().getInteger(
+                com.android.internal.R.integer.config_deskDockKeepsScreenOn) == 1);
     }
 
     public void disableCarMode() {
@@ -339,7 +367,7 @@
             }
         }
     }
-    
+
     final void updateLocked() {
         long ident = Binder.clearCallingIdentity();
         
@@ -421,6 +449,18 @@
                 mContext.sendOrderedBroadcast(new Intent(action), null,
                         mResultReceiver, null, Activity.RESULT_OK, null, null);
             }
+
+            // keep screen on when charging and in car mode
+            boolean keepScreenOn = mCharging &&
+                    ((mCarModeEnabled && mCarModeKeepsScreenOn) ||
+                     (mCurUiMode == Configuration.UI_MODE_TYPE_DESK && mDeskModeKeepsScreenOn));
+            if (keepScreenOn != mWakeLock.isHeld()) {
+                if (keepScreenOn) {
+                    mWakeLock.acquire();
+                } else {
+                    mWakeLock.release();
+                }
+            }
         } finally {
             Binder.restoreCallingIdentity(ident);
         }