Merge "WiredAccessoryManager: fix connected state logic for Extcon" into qt-r1-dev
diff --git a/api/test-current.txt b/api/test-current.txt
index a3ef9c4..87295fa 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -54,6 +54,7 @@
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getPackageImportance(String);
     method public long getTotalRam();
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidImportance(int);
+    method public static boolean isHighEndGfx();
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
     method public static void resumeAppSwitches() throws android.os.RemoteException;
     method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 17368b7..91b98c7 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -925,7 +925,7 @@
      * (which tends to consume a lot more RAM).
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
     static public boolean isHighEndGfx() {
         return !isLowRamDeviceStatic()
                 && !RoSystemProperties.CONFIG_AVOID_GFX_ACCEL
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e44c5f7..76d252e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4129,8 +4129,27 @@
          for higher refresh rates to be automatically used out of the box -->
     <integer name="config_defaultPeakRefreshRate">60</integer>
 
-    <!-- The default brightness threshold that allows to switch to higher refresh rate -->
-    <integer name="config_brightnessThresholdOfPeakRefreshRate">-1</integer>
+    <!-- The display uses different gamma curves for different refresh rates. It's hard for panel
+         vendor to tune the curves to have exact same brightness for different refresh rate. So
+         flicker could be observed at switch time. The issue is worse at the gamma lower end.
+         In addition, human eyes are more sensitive to the flicker at darker environment.
+         To prevent flicker, we only support higher refresh rates if the display brightness is above
+         a threshold. And the darker environment could have higher threshold.
+         For example, no higher refresh rate if
+             display brightness <= disp0 && ambient brightness <= amb0
+             || display brightness <= disp1 && ambient brightness <= amb1 -->
+    <integer-array translatable="false" name="config_brightnessThresholdsOfPeakRefreshRate">
+         <!--
+           <item>disp0</item>
+           <item>disp1</item>
+        -->
+    </integer-array>
+    <integer-array translatable="false" name="config_ambientThresholdsOfPeakRefreshRate">
+         <!--
+           <item>amb0</item>
+           <item>amb1</item>
+        -->
+    </integer-array>
 
     <!-- The type of the light sensor to be used by the display framework for things like
          auto-brightness. If unset, then it just gets the default sensor of type TYPE_LIGHT. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e19d1697..2791e1c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3788,7 +3788,8 @@
 
   <!-- For high refresh rate displays -->
   <java-symbol type="integer" name="config_defaultPeakRefreshRate" />
-  <java-symbol type="integer" name="config_brightnessThresholdOfPeakRefreshRate" />
+  <java-symbol type="array" name="config_brightnessThresholdsOfPeakRefreshRate" />
+  <java-symbol type="array" name="config_ambientThresholdsOfPeakRefreshRate" />
 
   <!-- For Auto-Brightness -->
   <java-symbol type="string" name="config_displayLightSensorType" />
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 69630c4..c7c648c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -237,6 +237,7 @@
                     MIN_DRAG_SIZE, getResources().getDisplayMetrics())
                     && !mUpdateMonitor.isFaceDetectionRunning()) {
                 mUpdateMonitor.requestFaceAuth();
+                mCallback.userActivity();
                 showMessage(null, null);
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index bc7174d..ea25ca8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -260,6 +260,7 @@
         boolean unlockAllowed = mKeyguardBypassController.onBiometricAuthenticated(
                 biometricSourceType);
         if (unlockAllowed) {
+            mKeyguardViewMediator.userActivity();
             startWakeAndUnlock(biometricSourceType);
         } else {
             Log.d(TAG, "onBiometricAuthenticated aborted by bypass controller");
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 884ecba..350df11 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -123,6 +123,8 @@
     /*package*/ void onAudioServerDied() {
         // Restore forced usage for communications and record
         synchronized (mDeviceStateLock) {
+            AudioSystem.setParameters(
+                    "BT_SCO=" + (mForcedUseForComm == AudioSystem.FORCE_BT_SCO ? "on" : "off"));
             onSetForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, "onAudioServerDied");
             onSetForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm, "onAudioServerDied");
         }
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 99341d1..4f33ebb0 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -303,6 +303,8 @@
     private final Spline mMinimumBrightnessSpline;
     private final ColorSpace mWideColorSpace;
 
+    private SensorManager mSensorManager;
+
     public DisplayManagerService(Context context) {
         this(context, new Injector());
     }
@@ -430,7 +432,7 @@
         }
 
         mDisplayModeDirector.setListener(new AllowedDisplayModeObserver());
-        mDisplayModeDirector.start();
+        mDisplayModeDirector.start(mSensorManager);
 
         mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
     }
@@ -2358,6 +2360,7 @@
                 };
                 mDisplayPowerController = new DisplayPowerController(
                         mContext, callbacks, handler, sensorManager, blanker);
+                mSensorManager = sensorManager;
             }
 
             mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 14bd2d8..78a48da 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -18,26 +18,41 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.display.DisplayManager;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.UserHandle;
+import android.os.PowerManager;
+import android.os.SystemClock;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.DisplayInfo;
 
 import com.android.internal.R;
+import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory;
+import com.android.server.display.whitebalance.AmbientFilter;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -74,7 +89,7 @@
     private final AppRequestObserver mAppRequestObserver;
     private final SettingsObserver mSettingsObserver;
     private final DisplayObserver mDisplayObserver;
-
+    private final BrightnessObserver mBrightnessObserver;
 
     private Listener mListener;
 
@@ -87,6 +102,8 @@
         mAppRequestObserver = new AppRequestObserver();
         mSettingsObserver = new SettingsObserver(context, handler);
         mDisplayObserver = new DisplayObserver(context, handler);
+        mBrightnessObserver = new BrightnessObserver(context, handler);
+
     }
 
     /**
@@ -96,15 +113,17 @@
      * This has to be deferred because the object may be constructed before the rest of the system
      * is ready.
      */
-    public void start() {
+    public void start(SensorManager sensorManager) {
         mSettingsObserver.observe();
         mDisplayObserver.observe();
         mSettingsObserver.observe();
+        mBrightnessObserver.observe(sensorManager);
         synchronized (mLock) {
             // We may have a listener already registered before the call to start, so go ahead and
             // notify them to pick up our newly initialized state.
             notifyAllowedModesChangedLocked();
         }
+
     }
 
     /**
@@ -315,6 +334,7 @@
             }
             mSettingsObserver.dumpLocked(pw);
             mAppRequestObserver.dumpLocked(pw);
+            mBrightnessObserver.dumpLocked(pw);
         }
     }
 
@@ -486,20 +506,15 @@
                 Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE);
         private final Uri mLowPowerModeSetting =
                 Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE);
-        private final Uri mBrightnessSetting =
-                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
 
         private final Context mContext;
         private final float mDefaultPeakRefreshRate;
-        private final int mBrightnessThreshold;
 
         SettingsObserver(@NonNull Context context, @NonNull Handler handler) {
             super(handler);
             mContext = context;
             mDefaultPeakRefreshRate = (float) context.getResources().getInteger(
                     R.integer.config_defaultPeakRefreshRate);
-            mBrightnessThreshold = context.getResources().getInteger(
-                    R.integer.config_brightnessThresholdOfPeakRefreshRate);
         }
 
         public void observe() {
@@ -508,14 +523,9 @@
                     UserHandle.USER_SYSTEM);
             cr.registerContentObserver(mLowPowerModeSetting, false /*notifyDescendants*/, this,
                     UserHandle.USER_SYSTEM);
-            if (mBrightnessThreshold >= 0) {
-                cr.registerContentObserver(mBrightnessSetting, false /*notifyDescendants*/, this,
-                    UserHandle.USER_SYSTEM);
-            }
             synchronized (mLock) {
                 updateRefreshRateSettingLocked();
                 updateLowPowerModeSettingLocked();
-                updateBrightnessSettingLocked();
             }
         }
 
@@ -526,8 +536,6 @@
                     updateRefreshRateSettingLocked();
                 } else if (mLowPowerModeSetting.equals(uri)) {
                     updateLowPowerModeSettingLocked();
-                } else if (mBrightnessThreshold >=0 && mBrightnessSetting.equals(uri)) {
-                    updateBrightnessSettingLocked();
                 }
             }
         }
@@ -542,6 +550,7 @@
                 vote = null;
             }
             updateVoteLocked(Vote.PRIORITY_LOW_POWER_MODE, vote);
+            mBrightnessObserver.onLowPowerModeEnabled(inLowPowerMode);
         }
 
         private void updateRefreshRateSettingLocked() {
@@ -549,23 +558,7 @@
                     Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate);
             Vote vote = Vote.forRefreshRates(0f, peakRefreshRate);
             updateVoteLocked(Vote.PRIORITY_USER_SETTING_REFRESH_RATE, vote);
-        }
-
-        private void updateBrightnessSettingLocked() {
-            int brightness = Settings.System.getInt(mContext.getContentResolver(),
-                    Settings.System.SCREEN_BRIGHTNESS, -1);
-
-            if (brightness < 0) {
-                return;
-            }
-
-            final Vote vote;
-            if (brightness <= mBrightnessThreshold) {
-                vote = Vote.forRefreshRates(0f, 60f);
-            } else {
-                vote = null;
-            }
-            updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, vote);
+            mBrightnessObserver.onPeakRefreshRateEnabled(peakRefreshRate > 60f);
         }
 
         public void dumpLocked(PrintWriter pw) {
@@ -715,4 +708,240 @@
             }
         }
     }
+
+    /**
+     * This class manages brightness threshold for switching between 60 hz and higher refresh rate.
+     * See more information at the definition of
+     * {@link R.array#config_brightnessThresholdsOfPeakRefreshRate} and
+     * {@link R.array#config_ambientThresholdsOfPeakRefreshRate}.
+     */
+    private class BrightnessObserver extends ContentObserver {
+        private final Uri mDisplayBrightnessSetting =
+                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
+
+        private final static int LIGHT_SENSOR_RATE_MS = 250;
+        private final int[] mDisplayBrightnessThresholds;
+        private final int[] mAmbientBrightnessThresholds;
+        // valid threshold if any item from the array >= 0
+        private boolean mShouldObserveDisplayChange;
+        private boolean mShouldObserveAmbientChange;
+
+        private SensorManager mSensorManager;
+        private Sensor mLightSensor;
+        // Take it as low brightness before valid sensor data comes
+        private float mAmbientLux = -1.0f;
+        private AmbientFilter mAmbientFilter;
+
+        private final Context mContext;
+        private ScreenStateReceiver mScreenStateReceiver;
+
+        // Enable light sensor only when screen is on, peak refresh rate enabled and low power mode
+        // off. After initialization, these states will be updated from the same handler thread.
+        private boolean mScreenOn = false;
+        private boolean mPeakRefreshRateEnabled = false;
+        private boolean mLowPowerModeEnabled = false;
+
+        BrightnessObserver(Context context, Handler handler) {
+            super(handler);
+            mContext = context;
+            mDisplayBrightnessThresholds = context.getResources().getIntArray(
+                    R.array.config_brightnessThresholdsOfPeakRefreshRate);
+            mAmbientBrightnessThresholds = context.getResources().getIntArray(
+                    R.array.config_ambientThresholdsOfPeakRefreshRate);
+            if (mDisplayBrightnessThresholds.length != mAmbientBrightnessThresholds.length) {
+                throw new RuntimeException("display brightness threshold array and ambient "
+                        + "brightness threshold array have different length");
+            }
+
+            mShouldObserveDisplayChange = checkShouldObserve(mDisplayBrightnessThresholds);
+            mShouldObserveAmbientChange = checkShouldObserve(mAmbientBrightnessThresholds);
+        }
+
+        public void observe(SensorManager sensorManager) {
+            if (mShouldObserveDisplayChange) {
+                final ContentResolver cr = mContext.getContentResolver();
+                cr.registerContentObserver(mDisplayBrightnessSetting,
+                        false /*notifyDescendants*/, this, UserHandle.USER_SYSTEM);
+            }
+
+            if (mShouldObserveAmbientChange) {
+                Resources resources = mContext.getResources();
+                String lightSensorType = resources.getString(
+                        com.android.internal.R.string.config_displayLightSensorType);
+
+                Sensor lightSensor = null;
+                if (!TextUtils.isEmpty(lightSensorType)) {
+                    List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
+                    for (int i = 0; i < sensors.size(); i++) {
+                        Sensor sensor = sensors.get(i);
+                        if (lightSensorType.equals(sensor.getStringType())) {
+                            lightSensor = sensor;
+                            break;
+                        }
+                    }
+                }
+
+                if (lightSensor == null) {
+                    lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+                }
+
+                if (lightSensor != null) {
+                    final Resources res = mContext.getResources();
+
+                    mAmbientFilter = DisplayWhiteBalanceFactory.createBrightnessFilter(res);
+                    mSensorManager = sensorManager;
+                    mLightSensor = lightSensor;
+
+                    // Intent.ACTION_SCREEN_ON is not sticky. Check current screen status.
+                    if (mContext.getSystemService(PowerManager.class).isInteractive()) {
+                        onScreenOn(true);
+                    }
+                    mScreenStateReceiver = new ScreenStateReceiver(mContext);
+                }
+            }
+
+            if (mShouldObserveDisplayChange || mShouldObserveAmbientChange) {
+                synchronized (mLock) {
+                    onBrightnessChangedLocked();
+                }
+            }
+        }
+
+        public void onPeakRefreshRateEnabled(boolean b) {
+            if (mShouldObserveAmbientChange && mPeakRefreshRateEnabled != b) {
+                mPeakRefreshRateEnabled = b;
+                updateSensorStatus();
+            }
+        }
+
+        public void onLowPowerModeEnabled(boolean b) {
+            if (mShouldObserveAmbientChange && mLowPowerModeEnabled != b) {
+                mLowPowerModeEnabled = b;
+                updateSensorStatus();
+            }
+        }
+
+        public void dumpLocked(PrintWriter pw) {
+            pw.println("  BrightnessObserver");
+
+            for (int d: mDisplayBrightnessThresholds) {
+                pw.println("    mDisplayBrightnessThreshold: " + d);
+            }
+
+            for (int d: mAmbientBrightnessThresholds) {
+                pw.println("    mAmbientBrightnessThreshold: " + d);
+            }
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri, int userId) {
+            synchronized (mLock) {
+                onBrightnessChangedLocked();
+            }
+        }
+
+        /**
+         * Checks to see if at least one value is positive, in which case it is necessary to listen
+         * to value changes.
+         */
+        private boolean checkShouldObserve(int[] a) {
+            for (int d: a) {
+                if (d >= 0) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        private void onBrightnessChangedLocked() {
+            int brightness = Settings.System.getInt(mContext.getContentResolver(),
+                    Settings.System.SCREEN_BRIGHTNESS, -1);
+
+            Vote vote = null;
+            for (int i = 0; i < mDisplayBrightnessThresholds.length; i++) {
+                int disp = mDisplayBrightnessThresholds[i];
+                int ambi = mAmbientBrightnessThresholds[i];
+
+                if (disp >= 0 && ambi >= 0) {
+                    if (brightness <= disp && mAmbientLux <= ambi) {
+                        vote = Vote.forRefreshRates(0f, 60f);
+                    }
+                } else if (disp >= 0) {
+                    if (brightness <= disp) {
+                        vote = Vote.forRefreshRates(0f, 60f);
+                    }
+                } else if (ambi >= 0) {
+                    if (mAmbientLux <= ambi) {
+                        vote = Vote.forRefreshRates(0f, 60f);
+                    }
+                }
+
+                if (vote != null) {
+                    break;
+                }
+            }
+
+            if (DEBUG) {
+                Slog.d(TAG, "Display brightness " + brightness + ", ambient lux " +  mAmbientLux +
+                        (vote != null ? " 60hz only" : " no refresh rate limit"));
+            }
+            updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, vote);
+        }
+
+        private void onScreenOn(boolean on) {
+            // Not check mShouldObserveAmbientChange because Screen status receiver is registered
+            // only when it is true.
+            if (mScreenOn != on) {
+                mScreenOn = on;
+                updateSensorStatus();
+            }
+        }
+
+        private void updateSensorStatus() {
+            if (mSensorManager == null || mLightSensorListener == null) {
+                return;
+            }
+
+            if (mScreenOn && !mLowPowerModeEnabled && mPeakRefreshRateEnabled) {
+                mSensorManager.registerListener(mLightSensorListener,
+                        mLightSensor, LIGHT_SENSOR_RATE_MS * 1000, mHandler);
+            } else {
+                mSensorManager.unregisterListener(mLightSensorListener);
+            }
+        }
+
+        private final SensorEventListener mLightSensorListener = new SensorEventListener() {
+            @Override
+            public void onSensorChanged(SensorEvent event) {
+                long now = SystemClock.uptimeMillis();
+                mAmbientFilter.addValue(now, event.values[0]);
+                mAmbientLux = mAmbientFilter.getEstimate(now);
+
+                synchronized (mLock) {
+                    onBrightnessChangedLocked();
+                }
+            }
+
+            @Override
+            public void onAccuracyChanged(Sensor sensor, int accuracy) {
+                // Not used.
+            }
+        };
+
+        private final class ScreenStateReceiver extends BroadcastReceiver {
+            public ScreenStateReceiver(Context context) {
+                IntentFilter filter = new IntentFilter();
+                filter.addAction(Intent.ACTION_SCREEN_OFF);
+                filter.addAction(Intent.ACTION_SCREEN_ON);
+                filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+                context.registerReceiver(this, filter, null, mHandler);
+            }
+
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                onScreenOn(Intent.ACTION_SCREEN_ON.equals(intent.getAction()));
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java b/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
index 123cd73..3580897 100644
--- a/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
+++ b/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
@@ -36,7 +36,7 @@
  * - {@link WeightedMovingAverageAmbientFilter}
  *   A weighted average prioritising recent changes.
  */
-abstract class AmbientFilter {
+abstract public class AmbientFilter {
 
     protected static final boolean DEBUG = false; // Enable for verbose logs.
 
@@ -156,8 +156,7 @@
     /**
      * A weighted average prioritising recent changes.
      */
-    @VisibleForTesting
-    public static class WeightedMovingAverageAmbientFilter extends AmbientFilter {
+    static class WeightedMovingAverageAmbientFilter extends AmbientFilter {
 
         // How long the latest ambient value change is predicted to last.
         private static final int PREDICTION_TIME = 100; // Milliseconds
diff --git a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
index 4df7d6b..bf0a1d1 100644
--- a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
+++ b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
@@ -115,8 +115,7 @@
      * Creates a BrightnessFilter which functions as a weighted moving average buffer for recent
      * brightness values.
      */
-    @VisibleForTesting
-    static AmbientFilter createBrightnessFilter(Resources resources) {
+    public static AmbientFilter createBrightnessFilter(Resources resources) {
         final int horizon = resources.getInteger(
                 com.android.internal.R.integer.config_displayWhiteBalanceBrightnessFilterHorizon);
         final float intercept = getFloat(resources,
@@ -129,7 +128,6 @@
                 + "expected config_displayWhiteBalanceBrightnessFilterIntercept");
     }
 
-
     /**
      * Creates an ambient color sensor instance to redirect sensor data to callbacks.
      */
diff --git a/services/core/java/com/android/server/locksettings/PasswordSlotManager.java b/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
index 5cbd237..4ef63c0 100644
--- a/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
+++ b/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
@@ -122,7 +122,7 @@
      */
     public void markSlotDeleted(int slot) throws RuntimeException {
         ensureSlotMapLoaded();
-        if (mSlotMap.containsKey(slot) && mSlotMap.get(slot) != getMode()) {
+        if (mSlotMap.containsKey(slot) && !mSlotMap.get(slot).equals(getMode())) {
             throw new RuntimeException("password slot " + slot + " cannot be deleted");
         }
         mSlotMap.remove(slot);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 0f96f99..8a9dfc7 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4998,6 +4998,9 @@
      *  - the cmd arg isn't the flattened component name of an existing activity:
      *    dump all activity whose component contains the cmd as a substring
      *  - A hex number of the ActivityRecord object instance.
+     * <p>
+     * The caller should not hold lock when calling this method because it will wait for the
+     * activities to complete the dump.
      *
      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
@@ -5050,29 +5053,28 @@
     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
             final ActivityRecord r, String[] args, boolean dumpAll) {
         String innerPrefix = prefix + "  ";
+        IApplicationThread appThread = null;
         synchronized (mGlobalLock) {
             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
             pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
             pw.print(" pid=");
-            if (r.hasProcess()) pw.println(r.app.getPid());
-            else pw.println("(not running)");
+            if (r.hasProcess()) {
+                pw.println(r.app.getPid());
+                appThread = r.app.getThread();
+            } else {
+                pw.println("(not running)");
+            }
             if (dumpAll) {
                 r.dump(pw, innerPrefix);
             }
         }
-        if (r.attachedToProcess()) {
+        if (appThread != null) {
             // flush anything that is already in the PrintWriter since the thread is going
             // to write to the file descriptor directly
             pw.flush();
-            try {
-                TransferPipe tp = new TransferPipe();
-                try {
-                    r.app.getThread().dumpActivity(tp.getWriteFd(),
-                            r.appToken, innerPrefix, args);
-                    tp.go(fd);
-                } finally {
-                    tp.kill();
-                }
+            try (TransferPipe tp = new TransferPipe()) {
+                appThread.dumpActivity(tp.getWriteFd(), r.appToken, innerPrefix, args);
+                tp.go(fd);
             } catch (IOException e) {
                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
             } catch (RemoteException e) {
@@ -7181,10 +7183,8 @@
         public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
                 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
                 boolean dumpFocusedStackOnly) {
-            synchronized (mGlobalLock) {
-                return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
-                        dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
-            }
+            return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti, dumpAll,
+                    dumpVisibleStacksOnly, dumpFocusedStackOnly);
         }
 
         @Override