Merge "Apps must opt into using icon badges."
diff --git a/api/current.txt b/api/current.txt
index aab29be..6880c0b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13230,7 +13230,7 @@
     method public void setFilterBitmap(boolean);
     method public void setFlags(int);
     method public void setFontFeatureSettings(java.lang.String);
-    method public void setFontVariationSettings(java.lang.String);
+    method public boolean setFontVariationSettings(java.lang.String);
     method public void setHinting(int);
     method public void setLetterSpacing(float);
     method public void setLinearText(boolean);
@@ -51263,7 +51263,7 @@
     method public void setExtractedText(android.view.inputmethod.ExtractedText);
     method public void setFilters(android.text.InputFilter[]);
     method public void setFontFeatureSettings(java.lang.String);
-    method public void setFontVariationSettings(java.lang.String);
+    method public boolean setFontVariationSettings(java.lang.String);
     method protected boolean setFrame(int, int, int, int);
     method public void setFreezesText(boolean);
     method public void setGravity(int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 5e6717c..3dac882 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -13965,7 +13965,7 @@
     method public void setFilterBitmap(boolean);
     method public void setFlags(int);
     method public void setFontFeatureSettings(java.lang.String);
-    method public void setFontVariationSettings(java.lang.String);
+    method public boolean setFontVariationSettings(java.lang.String);
     method public void setHinting(int);
     method public void setLetterSpacing(float);
     method public void setLinearText(boolean);
@@ -55092,7 +55092,7 @@
     method public void setExtractedText(android.view.inputmethod.ExtractedText);
     method public void setFilters(android.text.InputFilter[]);
     method public void setFontFeatureSettings(java.lang.String);
-    method public void setFontVariationSettings(java.lang.String);
+    method public boolean setFontVariationSettings(java.lang.String);
     method protected boolean setFrame(int, int, int, int);
     method public void setFreezesText(boolean);
     method public void setGravity(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index f91bbb9..a891fde 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -13268,7 +13268,7 @@
     method public void setFilterBitmap(boolean);
     method public void setFlags(int);
     method public void setFontFeatureSettings(java.lang.String);
-    method public void setFontVariationSettings(java.lang.String);
+    method public boolean setFontVariationSettings(java.lang.String);
     method public void setHinting(int);
     method public void setLetterSpacing(float);
     method public void setLinearText(boolean);
@@ -51641,7 +51641,7 @@
     method public void setExtractedText(android.view.inputmethod.ExtractedText);
     method public void setFilters(android.text.InputFilter[]);
     method public void setFontFeatureSettings(java.lang.String);
-    method public void setFontVariationSettings(java.lang.String);
+    method public boolean setFontVariationSettings(java.lang.String);
     method protected boolean setFrame(int, int, int, int);
     method public void setFreezesText(boolean);
     method public void setGravity(int);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7b84f689..146d2d3 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6788,6 +6788,13 @@
         public static final String NIGHT_DISPLAY_AUTO_MODE = "night_display_auto_mode";
 
         /**
+         * Control the color temperature of Night Display, represented in Kelvin.
+         * @hide
+         */
+        public static final String NIGHT_DISPLAY_COLOR_TEMPERATURE =
+                "night_display_color_temperature";
+
+        /**
          * Custom time when Night display is scheduled to activate.
          * Represented as milliseconds from midnight (e.g. 79200000 == 10pm).
          * @hide
@@ -7022,6 +7029,7 @@
             INCALL_POWER_BUTTON_BEHAVIOR,
             NIGHT_DISPLAY_CUSTOM_START_TIME,
             NIGHT_DISPLAY_CUSTOM_END_TIME,
+            NIGHT_DISPLAY_COLOR_TEMPERATURE,
             NIGHT_DISPLAY_AUTO_MODE,
             NIGHT_DISPLAY_ACTIVATED,
             SYNC_PARENT_SOUNDS,
@@ -7077,6 +7085,8 @@
 
             INSTANT_APP_SETTINGS.add(DEFAULT_INPUT_METHOD);
             INSTANT_APP_SETTINGS.add(ENABLED_INPUT_METHODS);
+
+            INSTANT_APP_SETTINGS.add(ANDROID_ID);
         }
 
         /**
@@ -10285,6 +10295,7 @@
             INSTANT_APP_SETTINGS.add(DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES);
             INSTANT_APP_SETTINGS.add(DEVELOPMENT_FORCE_RTL);
             INSTANT_APP_SETTINGS.add(EPHEMERAL_COOKIE_MAX_SIZE_BYTES);
+            INSTANT_APP_SETTINGS.add(AIRPLANE_MODE_ON);
         }
 
         /**
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 5d136dc..1d1fcc9 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -677,7 +677,6 @@
     protected synchronized void onDraw(Canvas canvas) {
         super.onDraw(canvas);
         drawThumb(canvas);
-
     }
 
     @Override
@@ -703,9 +702,9 @@
     }
 
     /**
-     * Draw the tick marks.
+     * @hide
      */
-    void drawTickMarks(Canvas canvas) {
+    protected void drawTickMarks(Canvas canvas) {
         if (mTickMark != null) {
             final int count = getMax() - getMin();
             if (count > 1) {
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index ec2adfb..cabf8ea 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -851,6 +851,13 @@
     }
 
     /**
+     * @hide
+     */
+    public boolean getMirrorForRtl() {
+        return mMirrorForRtl;
+    }
+
+    /**
      * Applies the progress tints in order of increasing specificity.
      */
     private void applyProgressTints() {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 52e8ec8..f2a7f25 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3808,23 +3808,28 @@
      * @param fontVariationSettings font variation settings. You can pass null or empty string as
      *                              no variation settings.
      *
+     * @return true if the given settings is effective to at least one font file underlying this
+     *         TextView. This function also returns true for empty settings string. Otherwise
+     *         returns false.
+     *
      * @see #getFontVariationSettings()
      * @see Paint#getFontVariationSettings() Paint.getFontVariationSettings()
      */
-    public void setFontVariationSettings(@Nullable String fontVariationSettings) {
+    public boolean setFontVariationSettings(@Nullable String fontVariationSettings) {
         final String existingSettings = mTextPaint.getFontVariationSettings();
         if (fontVariationSettings == existingSettings
                 || (fontVariationSettings != null
                         && fontVariationSettings.equals(existingSettings))) {
-            return;
+            return true;
         }
-        mTextPaint.setFontVariationSettings(fontVariationSettings);
+        boolean effective = mTextPaint.setFontVariationSettings(fontVariationSettings);
 
-        if (mLayout != null) {
+        if (effective && mLayout != null) {
             nullLayouts();
             requestLayout();
             invalidate();
         }
+        return effective;
     }
 
     /**
diff --git a/core/java/com/android/internal/app/NightDisplayController.java b/core/java/com/android/internal/app/NightDisplayController.java
index 68afe02..d19f1ec 100644
--- a/core/java/com/android/internal/app/NightDisplayController.java
+++ b/core/java/com/android/internal/app/NightDisplayController.java
@@ -46,7 +46,6 @@
     private static final String TAG = "NightDisplayController";
     private static final boolean DEBUG = false;
 
-    /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({ AUTO_MODE_DISABLED, AUTO_MODE_CUSTOM, AUTO_MODE_TWILIGHT })
     public @interface AutoMode {}
@@ -233,6 +232,65 @@
                 Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, endTime.toMillis(), mUserId);
     }
 
+    /**
+     * Returns the color temperature (in Kelvin) to tint the display when activated.
+     */
+    public int getColorTemperature() {
+        int colorTemperature = Secure.getIntForUser(mContext.getContentResolver(),
+                Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, -1, mUserId);
+        if (colorTemperature == -1) {
+            if (DEBUG) {
+                Slog.d(TAG, "Using default value for setting: "
+                    + Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE);
+            }
+            colorTemperature = getDefaultColorTemperature();
+        }
+        final int minimumTemperature = getMinimumColorTemperature();
+        final int maximumTemperature = getMaximumColorTemperature();
+        if (colorTemperature < minimumTemperature) {
+            colorTemperature = minimumTemperature;
+        } else if (colorTemperature > maximumTemperature) {
+            colorTemperature = maximumTemperature;
+        }
+
+        return colorTemperature;
+    }
+
+    /**
+     * Sets the current temperature.
+     *
+     * @param colorTemperature the temperature, in Kelvin.
+     * @return {@code true} if new temperature was set successfully.
+     */
+    public boolean setColorTemperature(int colorTemperature) {
+        return Secure.putIntForUser(mContext.getContentResolver(),
+            Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, colorTemperature, mUserId);
+    }
+
+    /**
+     * Returns the minimum allowed color temperature (in Kelvin) to tint the display when activated.
+     */
+    public int getMinimumColorTemperature() {
+        return mContext.getResources().getInteger(
+                R.integer.config_nightDisplayColorTemperatureMin);
+    }
+
+    /**
+     * Returns the maximum allowed color temperature (in Kelvin) to tint the display when activated.
+     */
+    public int getMaximumColorTemperature() {
+        return mContext.getResources().getInteger(
+                R.integer.config_nightDisplayColorTemperatureMax);
+    }
+
+    /**
+     * Returns the default color temperature (in Kelvin) to tint the display when activated.
+     */
+    public int getDefaultColorTemperature() {
+        return mContext.getResources().getInteger(
+                R.integer.config_nightDisplayColorTemperatureDefault);
+    }
+
     private void onSettingChanged(@NonNull String setting) {
         if (DEBUG) {
             Slog.d(TAG, "onSettingChanged: " + setting);
@@ -252,6 +310,9 @@
                 case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME:
                     mCallback.onCustomEndTimeChanged(getCustomEndTime());
                     break;
+                case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE:
+                    mCallback.onColorTemperatureChanged(getColorTemperature());
+                    break;
             }
         }
     }
@@ -278,6 +339,8 @@
                         false /* notifyForDescendants */, mContentObserver, mUserId);
                 cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME),
                         false /* notifyForDescendants */, mContentObserver, mUserId);
+                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE),
+                        false /* notifyForDescendants */, mContentObserver, mUserId);
             }
         }
     }
@@ -417,5 +480,12 @@
          * @param endTime the local time to automatically deactivate Night display
          */
         default void onCustomEndTimeChanged(LocalTime endTime) {}
+
+        /**
+         * Callback invoked when the color temperature changes.
+         *
+         * @param colorTemperature the color temperature to tint the screen
+         */
+        default void onColorTemperatureChanged(int colorTemperature) {}
     }
 }
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index 0cdc74f..d0b07d0 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -91,6 +91,24 @@
     Typeface::setDefault(face);
 }
 
+static jobject Typeface_getSupportedAxes(JNIEnv *env, jobject, jlong faceHandle) {
+    Typeface* face = reinterpret_cast<Typeface*>(faceHandle);
+    const std::unordered_set<minikin::AxisTag>& tagSet = face->fFontCollection->getSupportedTags();
+    const size_t length = tagSet.size();
+    if (length == 0) {
+        return nullptr;
+    }
+    std::vector<jint> tagVec(length);
+    int index = 0;
+    for (const auto& tag : tagSet) {
+        tagVec[index++] = tag;
+    }
+    std::sort(tagVec.begin(), tagVec.end());
+    const jintArray result = env->NewIntArray(length);
+    env->SetIntArrayRegion(result, 0, length, tagVec.data());
+    return result;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 static const JNINativeMethod gTypefaceMethods[] = {
@@ -103,6 +121,7 @@
     { "nativeCreateFromArray",    "([J)J",
                                            (void*)Typeface_createFromArray },
     { "nativeSetDefault",         "(J)V",   (void*)Typeface_setDefault },
+    { "nativeGetSupportedAxes",   "(J)[I",  (void*)Typeface_getSupportedAxes },
 };
 
 int register_android_graphics_Typeface(JNIEnv* env)
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 385f256..c6cd746 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -804,6 +804,16 @@
          Represented as milliseconds from midnight (e.g. 21600000 == 6am). -->
     <integer name="config_defaultNightDisplayCustomEndTime">21600000</integer>
 
+    <!-- Minimum color temperature, in Kelvin, supported by Night display. -->
+    <integer name="config_nightDisplayColorTemperatureMin">2596</integer>
+
+    <!-- Default color temperature, in Kelvin, to tint the screen when Night display is
+         activated. -->
+    <integer name="config_nightDisplayColorTemperatureDefault">2850</integer>
+
+    <!-- Maximum color temperature, in Kelvin, supported by Night display. -->
+    <integer name="config_nightDisplayColorTemperatureMax">4082</integer>
+
     <!-- Indicate whether to allow the device to suspend when the screen is off
          due to the proximity sensor.  This resource should only be set to true
          if the sensor HAL correctly handles the proximity sensor as a wake-up source.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7201eae..f6f29d9 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2767,6 +2767,9 @@
   <java-symbol type="integer" name="config_defaultNightDisplayAutoMode" />
   <java-symbol type="integer" name="config_defaultNightDisplayCustomStartTime" />
   <java-symbol type="integer" name="config_defaultNightDisplayCustomEndTime" />
+  <java-symbol type="integer" name="config_nightDisplayColorTemperatureDefault" />
+  <java-symbol type="integer" name="config_nightDisplayColorTemperatureMin" />
+  <java-symbol type="integer" name="config_nightDisplayColorTemperatureMax" />
 
   <!-- Default first user restrictions -->
   <java-symbol type="array" name="config_defaultFirstUserRestrictions" />
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 5d6aa8a..f4bf079 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -19,7 +19,9 @@
 import android.annotation.ColorInt;
 import android.annotation.NonNull;
 import android.annotation.Size;
+import android.graphics.FontListParser;
 import android.os.LocaleList;
+import android.text.FontConfig;
 import android.text.GraphicsOperations;
 import android.text.SpannableString;
 import android.text.SpannedString;
@@ -30,6 +32,9 @@
 import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Locale;
 
@@ -1531,21 +1536,46 @@
     /**
      * Set font variation settings.
      *
+     * This function does nothing if none of the settings is applicable to underlying font files.
+     *
      * @param settings font variation settings, e.g. "'wdth' 300, 'wght' 1.8"
      *
      * @see #getFontVariationSettings()
      *
      * @param settings the font variation settings. You can pass null or empty string as no
      *                 variation settings.
+     * @return true if the given settings is effective to at least one font file underlying this
+     *         typeface. This function also returns true for empty settings string. Otherwise
+     *         returns false
      */
-    public void setFontVariationSettings(String settings) {
+    public boolean setFontVariationSettings(String settings) {
         settings = TextUtils.nullIfEmpty(settings);
         if (settings == mFontVariationSettings
                 || (settings != null && settings.equals(mFontVariationSettings))) {
-            return;
+            return true;
+        }
+
+        if (settings == null || settings.length() == 0) {
+            mFontVariationSettings = null;
+            setTypeface(Typeface.createFromTypefaceWithVariation(mTypeface,
+                      Collections.emptyList()));
+            return true;
+        }
+
+        final ArrayList<FontConfig.Axis> axes = FontListParser.parseFontVariationSettings(settings);
+        final ArrayList<FontConfig.Axis> filteredAxes = new ArrayList<FontConfig.Axis>();
+        for (int i = 0; i < axes.size(); ++i) {
+            final FontConfig.Axis axis = axes.get(i);
+            if (mTypeface.isSupportedAxes(axis.getTag())) {
+                filteredAxes.add(axis);
+            }
+        }
+        if (filteredAxes.isEmpty()) {
+            return false;
         }
         mFontVariationSettings = settings;
-        setTypeface(Typeface.createFromTypefaceWithVariation(mTypeface, settings));
+        setTypeface(Typeface.createFromTypefaceWithVariation(mTypeface, filteredAxes));
+        return true;
     }
 
     /**
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 3416401..8511c1f 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -53,6 +53,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
+import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -116,6 +117,9 @@
 
     private int mStyle = 0;
 
+    private int[] mSupportedAxes;
+    private static final int[] EMPTY_AXES = {};
+
     private static void setDefault(Typeface t) {
         sDefaultTypeface = t;
         nativeSetDefault(t.native_instance);
@@ -492,10 +496,8 @@
 
     /** @hide */
     public static Typeface createFromTypefaceWithVariation(Typeface family,
-            String fontVariationSettings) {
+            List<FontConfig.Axis> axes) {
         final long ni = family == null ? 0 : family.native_instance;
-        ArrayList<FontConfig.Axis> axes =
-                FontListParser.parseFontVariationSettings(fontVariationSettings);
         return new Typeface(nativeCreateFromTypefaceWithVariation(ni, axes));
     }
 
@@ -788,6 +790,21 @@
         return result;
     }
 
+    /** @hide */
+    public boolean isSupportedAxes(int axis) {
+        if (mSupportedAxes == null) {
+            synchronized (this) {
+                if (mSupportedAxes == null) {
+                    mSupportedAxes = nativeGetSupportedAxes(native_instance);
+                    if (mSupportedAxes == null) {
+                        mSupportedAxes = EMPTY_AXES;
+                    }
+                }
+            }
+        }
+        return Arrays.binarySearch(mSupportedAxes, axis) > 0;
+    }
+
     private static native long nativeCreateFromTypeface(long native_instance, int style);
     private static native long nativeCreateFromTypefaceWithVariation(
             long native_instance, List<FontConfig.Axis> axes);
@@ -796,4 +813,5 @@
     private static native int  nativeGetStyle(long native_instance);
     private static native long nativeCreateFromArray(long[] familyArray);
     private static native void nativeSetDefault(long native_instance);
+    private static native int[] nativeGetSupportedAxes(long native_instance);
 }
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 812e4d8..daf14af 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -522,8 +522,10 @@
     SkDEBUGFAIL("SkScalar must be a float for these conversions to be valid");
 #endif
     const int ptCount = vertexCount >> 1;
-    mCanvas->drawVertices(vertexMode, ptCount, (SkPoint*)verts, (SkPoint*)texs,
-                          (SkColor*)colors, indices, indexCount, paint);
+    mCanvas->drawVertices(SkVertices::MakeCopy(vertexMode, ptCount, (SkPoint*)verts,
+                                               (SkPoint*)texs, (SkColor*)colors,
+                                               indexCount, indices),
+                          SkBlendMode::kModulate, paint);
 }
 
 // ----------------------------------------------------------------------------
@@ -560,23 +562,17 @@
     hwuiBitmap.getSkBitmap(&bitmap);
     const int ptCount = (meshWidth + 1) * (meshHeight + 1);
     const int indexCount = meshWidth * meshHeight * 6;
-
-    /*  Our temp storage holds 2 or 3 arrays.
-        texture points [ptCount * sizeof(SkPoint)]
-        optionally vertex points [ptCount * sizeof(SkPoint)] if we need a
-            copy to convert from float to fixed
-        indices [ptCount * sizeof(uint16_t)]
-    */
-    ssize_t storageSize = ptCount * sizeof(SkPoint); // texs[]
-    storageSize += indexCount * sizeof(uint16_t);  // indices[]
-
-
-#ifndef SK_SCALAR_IS_FLOAT
-    SkDEBUGFAIL("SkScalar must be a float for these conversions to be valid");
-#endif
-    std::unique_ptr<char[]> storage(new char[storageSize]);
-    SkPoint* texs = (SkPoint*)storage.get();
-    uint16_t* indices = (uint16_t*)(texs + ptCount);
+    uint32_t flags = SkVertices::kHasTexCoords_BuilderFlag;
+    if (colors) {
+        flags |= SkVertices::kHasColors_BuilderFlag;
+    }
+    SkVertices::Builder builder(SkCanvas::kTriangles_VertexMode, ptCount, indexCount, flags);
+    memcpy(builder.positions(), vertices, ptCount * sizeof(SkPoint));
+    if (colors) {
+        memcpy(builder.colors(), colors, ptCount * sizeof(SkColor));
+    }
+    SkPoint* texs = builder.texCoords();
+    uint16_t* indices = builder.indices();
 
     // cons up texture coordinates and indices
     {
@@ -625,7 +621,6 @@
             index += 1;
         }
         SkASSERT(indexPtr - indices == indexCount);
-        SkASSERT((char*)indexPtr - (char*)storage.get() == storageSize);
     }
 
     // double-check that we have legal indices
@@ -646,9 +641,7 @@
     sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
     tmpPaint.setShader(image->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode));
 
-    mCanvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, (SkPoint*)vertices,
-                         texs, (const SkColor*)colors, indices,
-                         indexCount, tmpPaint);
+    mCanvas->drawVertices(builder.detach(), SkBlendMode::kModulate, tmpPaint);
 }
 
 void SkiaCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk,
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index 20ca80b..f6e92dc 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -31,6 +31,7 @@
 #include <SkRSXform.h>
 #include <SkSurface.h>
 #include <SkTextBlobRunIterator.h>
+#include <SkVertices.h>
 
 namespace android {
 namespace uirenderer {
@@ -180,20 +181,20 @@
     }
 }
 
-void SkiaCanvasProxy::onDrawVertices(VertexMode mode, int vertexCount, const SkPoint vertices[],
-        const SkPoint texs[], const SkColor colors[], SkBlendMode, const uint16_t indices[],
-        int indexCount, const SkPaint& paint) {
+void SkiaCanvasProxy::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode,
+        const SkPaint& paint) {
     // TODO: should we pass through blendmode
     if (mFilterHwuiCalls) {
         return;
     }
     // convert the SkPoints into floats
     static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
-    const int floatCount = vertexCount << 1;
-    const float* vArray = &vertices[0].fX;
-    const float* tArray = (texs) ? &texs[0].fX : NULL;
-    const int* cArray = (colors) ? (int*)colors : NULL;
-    mCanvas->drawVertices(mode, floatCount, vArray, tArray, cArray, indices, indexCount, paint);
+    const int floatCount = vertices->vertexCount() << 1;
+    const float* vArray = (const float*)vertices->positions();
+    const float* tArray = (const float*)vertices->texCoords();
+    const int* cArray = (const int*)vertices->colors();
+    mCanvas->drawVertices(vertices->mode(), floatCount, vArray, tArray, cArray,
+            vertices->indices(), vertices->indexCount(), paint);
 }
 
 sk_sp<SkSurface> SkiaCanvasProxy::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) {
diff --git a/libs/hwui/SkiaCanvasProxy.h b/libs/hwui/SkiaCanvasProxy.h
index 3b1dd73..d11a779 100644
--- a/libs/hwui/SkiaCanvasProxy.h
+++ b/libs/hwui/SkiaCanvasProxy.h
@@ -75,10 +75,7 @@
             const SkPaint*);
     virtual void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst,
             const SkPaint*);
-    virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[],
-                                const SkPoint texs[], const SkColor colors[], SkBlendMode,
-                                const uint16_t indices[], int indexCount,
-                                const SkPaint&) override;
+    virtual void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
 
     virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
 
diff --git a/libs/hwui/tests/unit/FatalTestCanvas.h b/libs/hwui/tests/unit/FatalTestCanvas.h
index 4831722..03d9496 100644
--- a/libs/hwui/tests/unit/FatalTestCanvas.h
+++ b/libs/hwui/tests/unit/FatalTestCanvas.h
@@ -80,9 +80,7 @@
     void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) {
         ADD_FAILURE() << "onDrawPoints not expected in this test";
     }
-    void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[], const SkPoint texs[],
-            const SkColor colors[], SkBlendMode, const uint16_t indices[], int indexCount,
-            const SkPaint&) {
+    void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) {
         ADD_FAILURE() << "onDrawVertices not expected in this test";
     }
     void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int count,
diff --git a/packages/ExternalStorageProvider/AndroidManifest.xml b/packages/ExternalStorageProvider/AndroidManifest.xml
index 0b290ce..1072f95 100644
--- a/packages/ExternalStorageProvider/AndroidManifest.xml
+++ b/packages/ExternalStorageProvider/AndroidManifest.xml
@@ -9,6 +9,7 @@
     <application android:label="@string/app_label">
         <provider
             android:name=".ExternalStorageProvider"
+            android:label="@string/storage_description"
             android:authorities="com.android.externalstorage.documents"
             android:grantUriPermissions="true"
             android:exported="true"
diff --git a/packages/ExternalStorageProvider/res/values/strings.xml b/packages/ExternalStorageProvider/res/values/strings.xml
index 8b16d3c..324fb59 100644
--- a/packages/ExternalStorageProvider/res/values/strings.xml
+++ b/packages/ExternalStorageProvider/res/values/strings.xml
@@ -18,6 +18,9 @@
     <!-- Title of the external storage application [CHAR LIMIT=32] -->
     <string name="app_label">External Storage</string>
 
+    <!-- Meaningful storage location description shown to client applications [CHAR LIMIT=32] -->
+    <string name="storage_description">Local storage</string>
+
     <!-- Title for documents backend that offers internal storage. [CHAR LIMIT=24] -->
     <string name="root_internal_storage">Internal storage</string>
     <!-- Title for directory in which a user may store their own documents and files. [CHAR LIMIT=24] -->
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index 6e1385a..187e35a 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -94,10 +94,10 @@
                     // but the content has changed.
                     if (mNextCommand == null) {
                         if (mUpdateSpec.pages != null && (mDocumentInfo.changed
-                                || mDocumentInfo.writtenPages == null
+                                || mDocumentInfo.pagesWrittenToFile == null
                                 || (mDocumentInfo.info.getPageCount()
                                         != PrintDocumentInfo.PAGE_COUNT_UNKNOWN
-                                && !PageRangeUtils.contains(mDocumentInfo.writtenPages,
+                                && !PageRangeUtils.contains(mDocumentInfo.pagesWrittenToFile,
                                         mUpdateSpec.pages, mDocumentInfo.info.getPageCount())))) {
                             mNextCommand = new WriteCommand(mContext, mLooper,
                                     mPrintDocumentAdapter, mDocumentInfo,
@@ -106,9 +106,10 @@
                         } else {
                             if (mUpdateSpec.pages != null) {
                                 // If we have the requested pages, update which ones to be printed.
-                                mDocumentInfo.printedPages = PageRangeUtils.computePrintedPages(
-                                        mUpdateSpec.pages, mDocumentInfo.writtenPages,
-                                        mDocumentInfo.info.getPageCount());
+                                mDocumentInfo.pagesInFileToPrint =
+                                        PageRangeUtils.computeWhichPagesInFileToPrint(
+                                                mUpdateSpec.pages, mDocumentInfo.pagesWrittenToFile,
+                                                mDocumentInfo.info.getPageCount());
                             }
                             // Notify we are done.
                             mState = STATE_UPDATED;
@@ -514,8 +515,20 @@
         public PrintAttributes attributes;
         public Bundle metadata;
         public PrintDocumentInfo info;
-        public PageRange[] printedPages;
-        public PageRange[] writtenPages;
+
+        /**
+         * Which pages out of the ones written to the file to print. This is not indexed by the
+         * document pages, but by the page number in the file.
+         * <p>E.g. if a document has 10 pages, we want pages 4-5 and 7, but only page 3-9 are in the
+         * file. This would contain 1-2 and 4.</p>
+         *
+         * @see PageRangeUtils#computeWhichPagesInFileToPrint
+         */
+        public PageRange[] pagesInFileToPrint;
+
+        /** Pages of the whole document that are currently written to file */
+        public PageRange[] pagesWrittenToFile;
+
         public MutexFileProvider fileProvider;
         public boolean changed;
         public boolean updated;
@@ -783,8 +796,8 @@
             if (changed || !equalsIgnoreSize(mDocument.info, info)) {
                 // If the content changed we throw away all pages as
                 // we will request them again with the new content.
-                mDocument.writtenPages = null;
-                mDocument.printedPages = null;
+                mDocument.pagesWrittenToFile = null;
+                mDocument.pagesInFileToPrint = null;
                 mDocument.changed = true;
             }
 
@@ -1098,17 +1111,17 @@
             }
 
             PageRange[] writtenPages = PageRangeUtils.normalize(pages);
-            PageRange[] printedPages = PageRangeUtils.computePrintedPages(
+            PageRange[] printedPages = PageRangeUtils.computeWhichPagesInFileToPrint(
                     mPages, writtenPages, mPageCount);
 
             // Handle if we got invalid pages
             if (printedPages != null) {
-                mDocument.writtenPages = writtenPages;
-                mDocument.printedPages = printedPages;
+                mDocument.pagesWrittenToFile = writtenPages;
+                mDocument.pagesInFileToPrint = printedPages;
                 completed();
             } else {
-                mDocument.writtenPages = null;
-                mDocument.printedPages = null;
+                mDocument.pagesWrittenToFile = null;
+                mDocument.pagesInFileToPrint = null;
                 failed(mContext.getString(R.string.print_error_default_message));
             }
 
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 4b51917..f6df995 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -85,8 +85,8 @@
 import android.widget.ImageView;
 import android.widget.Spinner;
 import android.widget.TextView;
-
 import android.widget.Toast;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.printspooler.R;
@@ -120,6 +120,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.function.Consumer;
 
 public class PrintActivity extends Activity implements RemotePrintDocument.UpdateResultCallbacks,
         PrintErrorFragment.OnActionListener, PageAdapter.ContentCallbacks,
@@ -543,8 +544,8 @@
         // pages in the printed document.
         PrintDocumentInfo info = document.info;
         if (info != null) {
-            final int pageCount = PageRangeUtils.getNormalizedPageCount(document.writtenPages,
-                    getAdjustedPageCount(info));
+            final int pageCount = PageRangeUtils.getNormalizedPageCount(
+                    document.pagesWrittenToFile, getAdjustedPageCount(info));
             PrintDocumentInfo adjustedInfo = new PrintDocumentInfo.Builder(info.getName())
                     .setContentType(info.getContentType())
                     .setPageCount(pageCount)
@@ -558,7 +559,7 @@
             }
 
             mPrintJob.setDocumentInfo(adjustedInfo);
-            mPrintJob.setPages(document.printedPages);
+            mPrintJob.setPages(document.pagesInFileToPrint);
         }
 
         switch (mState) {
@@ -627,7 +628,7 @@
         // Update the preview controller.
         mPrintPreviewController.onContentUpdated(contentUpdated,
                 getAdjustedPageCount(documentInfo.info),
-                mPrintedDocument.getDocumentInfo().writtenPages,
+                mPrintedDocument.getDocumentInfo().pagesWrittenToFile,
                 mSelectedPages, mPrintJob.getAttributes().getMediaSize(),
                 mPrintJob.getAttributes().getMinMargins());
     }
@@ -2105,14 +2106,15 @@
         // If saving to PDF, apply the attibutes as we are acting as a print service.
         PrintAttributes attributes = mDestinationSpinnerAdapter.getPdfPrinter() == mCurrentPrinter
                 ?  mPrintJob.getAttributes() : null;
-        new DocumentTransformer(this, mPrintJob, mFileProvider, attributes, new Runnable() {
-            @Override
-            public void run() {
+        new DocumentTransformer(this, mPrintJob, mFileProvider, attributes, error -> {
+            if (error == null) {
                 if (writeToUri != null) {
                     mPrintedDocument.writeContent(getContentResolver(), writeToUri);
                 }
                 setState(STATE_PRINT_COMPLETED);
                 doFinish();
+            } else {
+                onPrintDocumentError(error);
             }
         }).transform();
     }
@@ -3096,11 +3098,11 @@
 
         private final PrintAttributes mAttributesToApply;
 
-        private final Runnable mCallback;
+        private final Consumer<String> mCallback;
 
         public DocumentTransformer(Context context, PrintJobInfo printJob,
                 MutexFileProvider fileProvider, PrintAttributes attributes,
-                Runnable callback) {
+                Consumer<String> callback) {
             mContext = context;
             mPrintJob = printJob;
             mFileProvider = fileProvider;
@@ -3112,7 +3114,7 @@
         public void transform() {
             // If we have only the pages we want, done.
             if (mPagesToShred.length <= 0 && mAttributesToApply == null) {
-                mCallback.run();
+                mCallback.accept(null);
                 return;
             }
 
@@ -3126,22 +3128,26 @@
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
             final IPdfEditor editor = IPdfEditor.Stub.asInterface(service);
-            new AsyncTask<Void, Void, Void>() {
+            new AsyncTask<Void, Void, String>() {
                 @Override
-                protected Void doInBackground(Void... params) {
+                protected String doInBackground(Void... params) {
                     // It's OK to access the data members as they are
                     // final and this code is the last one to touch
                     // them as shredding is the very last step, so the
                     // UI is not interactive at this point.
-                    doTransform(editor);
-                    updatePrintJob();
-                    return null;
+                    try {
+                        doTransform(editor);
+                        updatePrintJob();
+                        return null;
+                    } catch (IOException | RemoteException | IllegalStateException e) {
+                        return e.toString();
+                    }
                 }
 
                 @Override
-                protected void onPostExecute(Void aVoid) {
+                protected void onPostExecute(String error) {
                     mContext.unbindService(DocumentTransformer.this);
-                    mCallback.run();
+                    mCallback.accept(error);
                 }
             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
         }
@@ -3151,7 +3157,7 @@
             /* do nothing */
         }
 
-        private void doTransform(IPdfEditor editor) {
+        private void doTransform(IPdfEditor editor) throws IOException, RemoteException {
             File tempFile = null;
             ParcelFileDescriptor src = null;
             ParcelFileDescriptor dst = null;
@@ -3190,8 +3196,6 @@
                 in = new FileInputStream(tempFile);
                 out = new FileOutputStream(jobFile);
                 Streams.copy(in, out);
-            } catch (IOException|RemoteException e) {
-                Log.e(LOG_TAG, "Error dropping pages", e);
             } finally {
                 IoUtils.closeQuietly(src);
                 IoUtils.closeQuietly(dst);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/util/PageRangeUtils.java b/packages/PrintSpooler/src/com/android/printspooler/util/PageRangeUtils.java
index 7425c03..a36f583 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/util/PageRangeUtils.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/util/PageRangeUtils.java
@@ -394,33 +394,42 @@
         return pageRanges.getStart() == 0 && pageRanges.getEnd() == pageCount - 1;
     }
 
-    public static PageRange[] computePrintedPages(PageRange[] requestedPages,
-            PageRange[] writtenPages, int pageCount) {
+    /**
+     * Compute the pages of the file that correspond to the requested pages in the doc.
+     *
+     * @param pagesInDocRequested The requested pages, doc-indexed
+     * @param pagesWrittenToFile The pages in the file
+     * @param pageCount The number of pages in the doc
+     *
+     * @return The pages, file-indexed
+     */
+    public static PageRange[] computeWhichPagesInFileToPrint(PageRange[] pagesInDocRequested,
+            PageRange[] pagesWrittenToFile, int pageCount) {
         // Adjust the print job pages based on what was requested and written.
         // The cases are ordered in the most expected to the least expected
         // with a special case first where the app does not know the page count
         // so we ask for all to be written.
-        if (Arrays.equals(requestedPages, ALL_PAGES_RANGE)
+        if (Arrays.equals(pagesInDocRequested, ALL_PAGES_RANGE)
                 && pageCount == PrintDocumentInfo.PAGE_COUNT_UNKNOWN) {
             return ALL_PAGES_RANGE;
-        } else if (Arrays.equals(writtenPages, requestedPages)) {
+        } else if (Arrays.equals(pagesWrittenToFile, pagesInDocRequested)) {
             // We got a document with exactly the pages we wanted. Hence,
             // the printer has to print all pages in the data.
             return ALL_PAGES_RANGE;
-        } else if (Arrays.equals(writtenPages, ALL_PAGES_RANGE)) {
+        } else if (Arrays.equals(pagesWrittenToFile, ALL_PAGES_RANGE)) {
             // We requested specific pages but got all of them. Hence,
             // the printer has to print only the requested pages.
-            return requestedPages;
-        } else if (PageRangeUtils.contains(writtenPages, requestedPages, pageCount)) {
+            return pagesInDocRequested;
+        } else if (PageRangeUtils.contains(pagesWrittenToFile, pagesInDocRequested, pageCount)) {
             // We requested specific pages and got more but not all pages.
             // Hence, we have to offset appropriately the printed pages to
             // be based off the start of the written ones instead of zero.
             // The written pages are always non-null and not empty.
-            final int offset = -writtenPages[0].getStart();
-            PageRangeUtils.offset(requestedPages, offset);
-            return requestedPages;
-        } else if (Arrays.equals(requestedPages, ALL_PAGES_RANGE)
-                && isAllPages(writtenPages, pageCount)) {
+            final int offset = -pagesWrittenToFile[0].getStart();
+            PageRangeUtils.offset(pagesInDocRequested, offset);
+            return pagesInDocRequested;
+        } else if (Arrays.equals(pagesInDocRequested, ALL_PAGES_RANGE)
+                && isAllPages(pagesWrittenToFile, pageCount)) {
             // We requested all pages via the special constant and got all
             // of them as an explicit enumeration. Hence, the printer has
             // to print only the requested pages.
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index 336942a..c2ce7c9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -686,7 +686,11 @@
             }
 
             if (comparator != null) {
-                Collections.sort(filteredApps, comparator);
+                synchronized (mEntriesMap) {
+                    // Locking to ensure that the background handler does not mutate
+                    // the size of AppEntries used for ordering while sorting.
+                    Collections.sort(filteredApps, comparator);
+                }
             }
 
             synchronized (mRebuildSync) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index a549c73..07bd242 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -278,7 +278,8 @@
      */
     private static final Intent USER_PRESENT_INTENT = new Intent(Intent.ACTION_USER_PRESENT)
             .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
-                    | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+                    | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
 
     /**
      * {@link #setKeyguardEnabled} waits on this condition when it reenables
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index b7b4a3b..8da17fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -23,6 +23,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 
+import com.android.internal.widget.CachingIconView;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
@@ -126,7 +127,12 @@
         super.setDark(dark, fade, delay);
         if (mDark == dark) return;
         mDark = dark;
-        mShelfIcons.setDark(dark, fade, delay);
+        if (fade) {
+            mViewInvertHelper.fade(dark, delay);
+        } else {
+            mViewInvertHelper.update(dark);
+        }
+        mShelfIcons.setAmbient(dark);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index ffc4e8d..1101701 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -27,7 +27,6 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -47,7 +46,6 @@
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.statusbar.notification.NotificationIconDozeHelper;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 
 import java.text.NumberFormat;
@@ -101,6 +99,7 @@
     private int mDensity;
     private float mIconScale = 1.0f;
     private final Paint mDotPaint = new Paint();
+    private boolean mDotVisible;
     private float mDotRadius;
     private int mStaticDotRadius;
     private int mVisibleState = STATE_ICON;
@@ -111,8 +110,6 @@
     private OnVisibilityChangedListener mOnVisibilityChangedListener;
     private int mDrawableColor;
     private int mIconColor;
-    private int mDecorColor;
-    private float mDarkAmount;
     private ValueAnimator mColorAnimator;
     private int mCurrentSetColor = NO_COLOR;
     private int mAnimationStartColor = NO_COLOR;
@@ -122,7 +119,6 @@
                 animation.getAnimatedFraction());
         setColorInternal(newColor);
     };
-    private final NotificationIconDozeHelper mDozer;
 
     public StatusBarIconView(Context context, String slot, Notification notification) {
         this(context, slot, notification, false);
@@ -131,7 +127,6 @@
     public StatusBarIconView(Context context, String slot, Notification notification,
             boolean blocked) {
         super(context);
-        mDozer = new NotificationIconDozeHelper(context);
         mBlocked = blocked;
         mSlot = slot;
         mNumberPain = new Paint();
@@ -195,7 +190,6 @@
 
     public StatusBarIconView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mDozer = new NotificationIconDozeHelper(context);
         mBlocked = false;
         mAlwaysScaleIcon = true;
         updateIconScale();
@@ -472,19 +466,7 @@
      * to the drawable.
      */
     public void setDecorColor(int iconTint) {
-        mDecorColor = iconTint;
-        updateDecorColor();
-    }
-
-    private void updateDecorColor() {
-        int color = NotificationUtils.interpolateColors(mDecorColor, Color.WHITE, mDarkAmount);
-        if (mDotPaint.getColor() != color) {
-            mDotPaint.setColor(color);
-
-            if (mDotAppearAmount != 0) {
-                invalidate();
-            }
-        }
+        mDotPaint.setColor(iconTint);
     }
 
     /**
@@ -495,7 +477,6 @@
         mDrawableColor = color;
         setColorInternal(color);
         mIconColor = color;
-        mDozer.setColor(color);
     }
 
     private void setColorInternal(int color) {
@@ -668,14 +649,6 @@
         mOnVisibilityChangedListener = listener;
     }
 
-    public void setDark(boolean dark, boolean fade, long delay) {
-        mDozer.setImageDark(this, dark, fade, delay, mIconColor != NO_COLOR);
-        mDozer.setIntensityDark(f -> {
-            mDarkAmount = f;
-            updateDecorColor();
-        }, dark, fade, delay);
-    }
-
     public interface OnVisibilityChangedListener {
         void onVisibilityChanged(int newVisibility);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
index bca4b43..3efa29f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -18,7 +18,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.content.Context;
+import android.animation.ValueAnimator;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
 import android.view.View;
@@ -38,8 +38,8 @@
     private boolean mIsLegacy;
     private int mLegacyColor;
 
-    protected NotificationCustomViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
-        super(ctx, view, row);
+    protected NotificationCustomViewWrapper(View view, ExpandableNotificationRow row) {
+        super(view, row);
         mInvertHelper = new ViewInvertHelper(view, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mLegacyColor = row.getContext().getColor(R.color.notification_legacy_background_color);
     }
@@ -67,11 +67,13 @@
     }
 
     protected void fadeGrayscale(final boolean dark, long delay) {
-        getDozer().startIntensityAnimation(animation -> {
-            getDozer().updateGrayscaleMatrix((float) animation.getAnimatedValue());
-            mGreyPaint.setColorFilter(
-                    new ColorMatrixColorFilter(getDozer().getGrayscaleColorMatrix()));
-            mView.setLayerPaint(mGreyPaint);
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                updateGrayscaleMatrix((float) animation.getAnimatedValue());
+                mGreyPaint.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
+                mView.setLayerPaint(mGreyPaint);
+            }
         }, dark, delay, new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -84,9 +86,9 @@
 
     protected void updateGrayscale(boolean dark) {
         if (dark) {
-            getDozer().updateGrayscaleMatrix(1f);
+            updateGrayscaleMatrix(1f);
             mGreyPaint.setColorFilter(
-                    new ColorMatrixColorFilter(getDozer().getGrayscaleColorMatrix()));
+                    new ColorMatrixColorFilter(mGrayscaleColorMatrix));
             mView.setLayerPaint(mGreyPaint);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
deleted file mode 100644
index d592c5f..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.statusbar.notification;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.widget.ImageView;
-
-import com.android.systemui.Interpolators;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
-
-import java.util.function.Consumer;
-
-public class NotificationDozeHelper {
-    private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
-
-    public void fadeGrayscale(final ImageView target, final boolean dark, long delay) {
-        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                updateGrayscaleMatrix((float) animation.getAnimatedValue());
-                target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
-            }
-        }, dark, delay, new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (!dark) {
-                    target.setColorFilter(null);
-                }
-            }
-        });
-    }
-
-    public void updateGrayscale(ImageView target, boolean dark) {
-        if (dark) {
-            updateGrayscaleMatrix(1f);
-            target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
-        } else {
-            target.setColorFilter(null);
-        }
-    }
-
-    public void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener,
-            boolean dark, long delay, Animator.AnimatorListener listener) {
-        float startIntensity = dark ? 0f : 1f;
-        float endIntensity = dark ? 1f : 0f;
-        ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
-        animator.addUpdateListener(updateListener);
-        animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
-        animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
-        animator.setStartDelay(delay);
-        if (listener != null) {
-            animator.addListener(listener);
-        }
-        animator.start();
-    }
-
-    public void setIntensityDark(Consumer<Float> listener, boolean dark,
-            boolean animate, long delay) {
-        if (animate) {
-            startIntensityAnimation(a -> listener.accept((Float) a.getAnimatedValue()), dark, delay,
-                    null /* listener */);
-        } else {
-            listener.accept(dark ? 1f : 0f);
-        }
-    }
-
-    public void updateGrayscaleMatrix(float intensity) {
-        mGrayscaleColorMatrix.setSaturation(1 - intensity);
-    }
-
-    public ColorMatrix getGrayscaleColorMatrix() {
-        return mGrayscaleColorMatrix;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index 1ffc944..38e4ec1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -16,10 +16,17 @@
 
 package com.android.systemui.statusbar.notification;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
 import android.app.Notification;
 import android.content.Context;
+import android.graphics.Color;
 import android.graphics.ColorFilter;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
 import android.util.ArraySet;
 import android.view.NotificationHeaderView;
 import android.view.View;
@@ -30,6 +37,7 @@
 import android.widget.TextView;
 
 import com.android.systemui.Interpolators;
+import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
@@ -47,6 +55,10 @@
 
     private static final Interpolator LOW_PRIORITY_HEADER_CLOSE
             = new PathInterpolator(0.4f, 0f, 0.7f, 1f);
+    private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter(
+            0, PorterDuff.Mode.SRC_ATOP);
+    private final int mIconDarkAlpha;
+    private final int mIconDarkColor = 0xffffffff;
 
     protected final ViewInvertHelper mInvertHelper;
     protected final ViewTransformationHelper mTransformationHelper;
@@ -62,7 +74,8 @@
     private boolean mTransformLowPriorityTitle;
 
     protected NotificationHeaderViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
-        super(ctx, view, row);
+        super(view, row);
+        mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
         mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mTransformationHelper = new ViewTransformationHelper();
 
@@ -95,16 +108,6 @@
         updateInvertHelper();
     }
 
-    @Override
-    protected NotificationDozeHelper createDozer(Context ctx) {
-        return new NotificationIconDozeHelper(ctx);
-    }
-
-    @Override
-    protected NotificationIconDozeHelper getDozer() {
-        return (NotificationIconDozeHelper) super.getDozer();
-    }
-
     protected void resolveHeaderViews() {
         mIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon);
         mHeaderText = (TextView) mView.findViewById(com.android.internal.R.id.header_text);
@@ -113,7 +116,6 @@
         mColor = resolveColor(mExpandButton);
         mNotificationHeader = (NotificationHeaderView) mView.findViewById(
                 com.android.internal.R.id.notification_header);
-        getDozer().setColor(mColor);
     }
 
     private int resolveColor(ImageView icon) {
@@ -221,8 +223,90 @@
             // It also may lead to bugs where the icon isn't correctly greyed out.
             boolean hadColorFilter = mNotificationHeader.getOriginalIconColor()
                     != NotificationHeaderView.NO_COLOR;
+            if (fade) {
+                if (hadColorFilter) {
+                    fadeIconColorFilter(mIcon, dark, delay);
+                    fadeIconAlpha(mIcon, dark, delay);
+                } else {
+                    fadeGrayscale(mIcon, dark, delay);
+                }
+            } else {
+                if (hadColorFilter) {
+                    updateIconColorFilter(mIcon, dark);
+                    updateIconAlpha(mIcon, dark);
+                } else {
+                    updateGrayscale(mIcon, dark);
+                }
+            }
+        }
+    }
 
-            getDozer().setImageDark(mIcon, dark, fade, delay, !hadColorFilter);
+    private void fadeIconColorFilter(final ImageView target, boolean dark, long delay) {
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                updateIconColorFilter(target, (Float) animation.getAnimatedValue());
+            }
+        }, dark, delay, null /* listener */);
+    }
+
+    private void fadeIconAlpha(final ImageView target, boolean dark, long delay) {
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                float t = (float) animation.getAnimatedValue();
+                target.setImageAlpha((int) (255 * (1f - t) + mIconDarkAlpha * t));
+            }
+        }, dark, delay, null /* listener */);
+    }
+
+    protected void fadeGrayscale(final ImageView target, final boolean dark, long delay) {
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                updateGrayscaleMatrix((float) animation.getAnimatedValue());
+                target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
+            }
+        }, dark, delay, new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!dark) {
+                    target.setColorFilter(null);
+                }
+            }
+        });
+    }
+
+    private void updateIconColorFilter(ImageView target, boolean dark) {
+        updateIconColorFilter(target, dark ? 1f : 0f);
+    }
+
+    private void updateIconColorFilter(ImageView target, float intensity) {
+        int color = interpolateColor(mColor, mIconDarkColor, intensity);
+        mIconColorFilter.setColor(color);
+        Drawable iconDrawable = target.getDrawable();
+
+        // Also, the notification might have been modified during the animation, so background
+        // might be null here.
+        if (iconDrawable != null) {
+            Drawable d = iconDrawable.mutate();
+            // DrawableContainer ignores the color filter if it's already set, so clear it first to
+            // get it set and invalidated properly.
+            d.setColorFilter(null);
+            d.setColorFilter(mIconColorFilter);
+        }
+    }
+
+    private void updateIconAlpha(ImageView target, boolean dark) {
+        target.setImageAlpha(dark ? mIconDarkAlpha : 255);
+    }
+
+    protected void updateGrayscale(ImageView target, boolean dark) {
+        if (dark) {
+            updateGrayscaleMatrix(1f);
+            target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
+        } else {
+            target.setColorFilter(null);
         }
     }
 
@@ -232,6 +316,22 @@
         mNotificationHeader.setOnClickListener(expandable ? onClickListener : null);
     }
 
+    private static int interpolateColor(int source, int target, float t) {
+        int aSource = Color.alpha(source);
+        int rSource = Color.red(source);
+        int gSource = Color.green(source);
+        int bSource = Color.blue(source);
+        int aTarget = Color.alpha(target);
+        int rTarget = Color.red(target);
+        int gTarget = Color.green(target);
+        int bTarget = Color.blue(target);
+        return Color.argb(
+                (int) (aSource * (1f - t) + aTarget * t),
+                (int) (rSource * (1f - t) + rTarget * t),
+                (int) (gSource * (1f - t) + gTarget * t),
+                (int) (bSource * (1f - t) + bTarget * t));
+    }
+
     @Override
     public NotificationHeaderView getNotificationHeader() {
         return mNotificationHeader;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java
deleted file mode 100644
index 9f79ef2..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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.statusbar.notification;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.drawable.Drawable;
-import android.widget.ImageView;
-
-import com.android.systemui.R;
-
-public class NotificationIconDozeHelper extends NotificationDozeHelper {
-
-    private final int mImageDarkAlpha;
-    private final int mImageDarkColor = 0xffffffff;
-    private final PorterDuffColorFilter mImageColorFilter = new PorterDuffColorFilter(
-            0, PorterDuff.Mode.SRC_ATOP);
-
-    private int mColor = Color.BLACK;
-
-    public NotificationIconDozeHelper(Context ctx) {
-        mImageDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
-    }
-
-    public void setColor(int color) {
-        mColor = color;
-    }
-
-    public void setImageDark(ImageView target, boolean dark, boolean fade, long delay,
-            boolean useGrayscale) {
-        if (fade) {
-            if (!useGrayscale) {
-                fadeImageColorFilter(target, dark, delay);
-                fadeImageAlpha(target, dark, delay);
-            } else {
-                fadeGrayscale(target, dark, delay);
-            }
-        } else {
-            if (!useGrayscale) {
-                updateImageColorFilter(target, dark);
-                updateImageAlpha(target, dark);
-            } else {
-                updateGrayscale(target, dark);
-            }
-        }
-    }
-
-    private void fadeImageColorFilter(final ImageView target, boolean dark, long delay) {
-        startIntensityAnimation(animation -> {
-            updateImageColorFilter(target, (Float) animation.getAnimatedValue());
-        }, dark, delay, null /* listener */);
-    }
-
-    private void fadeImageAlpha(final ImageView target, boolean dark, long delay) {
-        startIntensityAnimation(animation -> {
-            float t = (float) animation.getAnimatedValue();
-            target.setImageAlpha((int) (255 * (1f - t) + mImageDarkAlpha * t));
-        }, dark, delay, null /* listener */);
-    }
-
-    private void updateImageColorFilter(ImageView target, boolean dark) {
-        updateImageColorFilter(target, dark ? 1f : 0f);
-    }
-
-    private void updateImageColorFilter(ImageView target, float intensity) {
-        int color = NotificationUtils.interpolateColors(mColor, mImageDarkColor, intensity);
-        mImageColorFilter.setColor(color);
-        Drawable imageDrawable = target.getDrawable();
-
-        // Also, the notification might have been modified during the animation, so background
-        // might be null here.
-        if (imageDrawable != null) {
-            Drawable d = imageDrawable.mutate();
-            // DrawableContainer ignores the color filter if it's already set, so clear it first to
-            // get it set and invalidated properly.
-            d.setColorFilter(null);
-            d.setColorFilter(mImageColorFilter);
-        }
-    }
-
-    private void updateImageAlpha(ImageView target, boolean dark) {
-        target.setImageAlpha(dark ? mImageDarkAlpha : 255);
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index f0b6b2e..846d03a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification;
 
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Color;
 import android.service.notification.StatusBarNotification;
@@ -45,8 +46,7 @@
     private int mContentHeight;
     private int mMinHeightHint;
 
-    protected NotificationTemplateViewWrapper(Context ctx, View view,
-            ExpandableNotificationRow row) {
+    protected NotificationTemplateViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
         super(ctx, view, row);
         mTransformationHelper.setCustomTransformation(
                 new ViewTransformationHelper.CustomTransformation() {
@@ -154,20 +154,16 @@
         // This also clears the existing types
         super.updateTransformedTypes();
         if (mTitle != null) {
-            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE,
-                    mTitle);
+            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE, mTitle);
         }
         if (mText != null) {
-            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TEXT,
-                    mText);
+            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TEXT, mText);
         }
         if (mPicture != null) {
-            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_IMAGE,
-                    mPicture);
+            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_IMAGE, mPicture);
         }
         if (mProgressBar != null) {
-            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_PROGRESS,
-                    mProgressBar);
+            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_PROGRESS, mProgressBar);
         }
     }
 
@@ -177,7 +173,7 @@
             return;
         }
         super.setDark(dark, fade, delay);
-        setPictureDark(dark, fade, delay);
+        setPictureGrayscale(dark, fade, delay);
         setProgressBarDark(dark, fade, delay);
     }
 
@@ -192,9 +188,12 @@
     }
 
     private void fadeProgressDark(final ProgressBar target, final boolean dark, long delay) {
-        getDozer().startIntensityAnimation(animation -> {
-            float t = (float) animation.getAnimatedValue();
-            updateProgressDark(target, t);
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                float t = (float) animation.getAnimatedValue();
+                updateProgressDark(target, t);
+            }
         }, dark, delay, null /* listener */);
     }
 
@@ -208,9 +207,13 @@
         updateProgressDark(target, dark ? 1f : 0f);
     }
 
-    private void setPictureDark(boolean dark, boolean fade, long delay) {
+    protected void setPictureGrayscale(boolean grayscale, boolean fade, long delay) {
         if (mPicture != null) {
-            getDozer().setImageDark(mPicture, dark, fade, delay, true /* useGrayscale */);
+            if (fade) {
+                fadeGrayscale(mPicture, grayscale, delay);
+            } else {
+                updateGrayscale(mPicture, grayscale);
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index c86616b..c85e8d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -16,17 +16,24 @@
 
 package com.android.systemui.statusbar.notification;
 
+import android.animation.Animator;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Color;
+import android.graphics.ColorMatrix;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.service.notification.StatusBarNotification;
 import android.support.v4.graphics.ColorUtils;
 import android.view.NotificationHeaderView;
 import android.view.View;
 
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
  * Wraps the actual notification content view; used to implement behaviors which are different for
@@ -34,14 +41,14 @@
  */
 public abstract class NotificationViewWrapper implements TransformableView {
 
+    protected final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
     protected final View mView;
     protected final ExpandableNotificationRow mRow;
-    private final NotificationDozeHelper mDozer;
-
     protected boolean mDark;
     private int mBackgroundColor = 0;
     protected boolean mShouldInvertDark;
     protected boolean mDarkInitialized = false;
+    private boolean mForcedInvisible;
 
     public static NotificationViewWrapper wrap(Context ctx, View v, ExpandableNotificationRow row) {
         if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
@@ -58,22 +65,13 @@
         } else if (v instanceof NotificationHeaderView) {
             return new NotificationHeaderViewWrapper(ctx, v, row);
         } else {
-            return new NotificationCustomViewWrapper(ctx, v, row);
+            return new NotificationCustomViewWrapper(v, row);
         }
     }
 
-    protected NotificationViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
+    protected NotificationViewWrapper(View view, ExpandableNotificationRow row) {
         mView = view;
         mRow = row;
-        mDozer = createDozer(ctx);
-    }
-
-    protected NotificationDozeHelper createDozer(Context ctx) {
-        return new NotificationIconDozeHelper(mView.getContext());
-    }
-
-    protected NotificationDozeHelper getDozer() {
-        return mDozer;
     }
 
     /**
@@ -114,6 +112,26 @@
                 || ColorUtils.calculateLuminance(backgroundColor) > 0.5;
     }
 
+
+    protected void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener,
+            boolean dark, long delay, Animator.AnimatorListener listener) {
+        float startIntensity = dark ? 0f : 1f;
+        float endIntensity = dark ? 1f : 0f;
+        ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
+        animator.addUpdateListener(updateListener);
+        animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
+        animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+        animator.setStartDelay(delay);
+        if (listener != null) {
+            animator.addListener(listener);
+        }
+        animator.start();
+    }
+
+    protected void updateGrayscaleMatrix(float intensity) {
+        mGrayscaleColorMatrix.setSaturation(1 - intensity);
+    }
+
     /**
      * Update the appearance of the expand button.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index dee15d8..3706dc8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -95,7 +95,7 @@
     private int mActualLayoutWidth = NO_VALUE;
     private float mActualPaddingEnd = NO_VALUE;
     private float mActualPaddingStart = NO_VALUE;
-    private boolean mDark;
+    private boolean mCentered;
     private boolean mChangingViewPositions;
     private int mAddAnimationStartIndex = -1;
     private int mCannedAnimationStartIndex = -1;
@@ -183,9 +183,6 @@
                 mAddAnimationStartIndex = Math.min(mAddAnimationStartIndex, childIndex);
             }
         }
-        if (mDark && child instanceof StatusBarIconView) {
-            ((StatusBarIconView) child).setDark(mDark, false, 0);
-        }
     }
 
     @Override
@@ -315,8 +312,7 @@
                 numDots++;
             }
         }
-        boolean center = mDark;
-        if (center && translationX < getLayoutEnd()) {
+        if (mCentered && translationX < getLayoutEnd()) {
             float delta = (getLayoutEnd() - translationX) / 2;
             for (int i = 0; i < childCount; i++) {
                 View view = getChildAt(i);
@@ -394,15 +390,9 @@
         mChangingViewPositions = changingViewPositions;
     }
 
-    public void setDark(boolean dark, boolean fade, long delay) {
-        mDark = dark;
+    public void setAmbient(boolean ambient) {
+        mCentered = ambient;
         mDisallowNextAnimation = true;
-        for (int i = 0; i < getChildCount(); i++) {
-            View view = getChildAt(i);
-            if (view instanceof StatusBarIconView) {
-                ((StatusBarIconView) view).setDark(dark, fade, delay);
-            }
-        }
     }
 
     public IconState getIconState(StatusBarIconView icon) {
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 179b3d0..c6af290 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -954,10 +954,12 @@
         mTimeTickSender = PendingIntent.getBroadcastAsUser(getContext(), 0,
                 new Intent(Intent.ACTION_TIME_TICK).addFlags(
                         Intent.FLAG_RECEIVER_REGISTERED_ONLY
-                        | Intent.FLAG_RECEIVER_FOREGROUND), 0,
+                        | Intent.FLAG_RECEIVER_FOREGROUND
+                        | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS), 0,
                         UserHandle.ALL);
         Intent intent = new Intent(Intent.ACTION_DATE_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
+                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
         mDateChangeSender = PendingIntent.getBroadcastAsUser(getContext(), 0, intent,
                 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, UserHandle.ALL);
         
@@ -1034,7 +1036,8 @@
 
         if (timeZoneWasChanged) {
             Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
-            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
+                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
             intent.putExtra("time-zone", zone.getID());
             getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
         }
@@ -2518,7 +2521,8 @@
                         Intent intent = new Intent(Intent.ACTION_TIME_CHANGED);
                         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
                                 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
-                                | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+                                | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+                                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
                         getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
 
                         // The world has changed on us, so we need to re-evaluate alarms
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index c946d09..2067620 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -146,7 +146,6 @@
     private final LockPatternUtils mLockPatternUtils;
     private final NotificationManager mNotificationManager;
     private final UserManager mUserManager;
-    private final DevicePolicyManager mDevicePolicyManager;
     private final IActivityManager mActivityManager;
 
     private final KeyStore mKeyStore;
@@ -385,7 +384,6 @@
         mStorage = injector.getStorage();
         mNotificationManager = injector.getNotificationManager();
         mUserManager = injector.getUserManager();
-        mDevicePolicyManager = injector.getDevicePolicyManager();
         mStrongAuthTracker = injector.getStrongAuthTracker();
         mStrongAuthTracker.register(mStrongAuth);
 
@@ -2214,20 +2212,21 @@
                 Slog.i(TAG, "Managed profile can have escrow token");
                 return;
             }
+            DevicePolicyManager dpm = mInjector.getDevicePolicyManager();
             // Devices with Device Owner should have escrow enabled on all users.
-            if (mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser() != null) {
+            if (dpm.getDeviceOwnerComponentOnAnyUser() != null) {
                 Slog.i(TAG, "Corp-owned device can have escrow token");
                 return;
             }
             // We could also have a profile owner on the given (non-managed) user for unicorn cases
-            if (mDevicePolicyManager.getProfileOwnerAsUser(userId) != null) {
+            if (dpm.getProfileOwnerAsUser(userId) != null) {
                 Slog.i(TAG, "User with profile owner can have escrow token");
                 return;
             }
             // If the device is yet to be provisioned (still in SUW), there is still
             // a chance that Device Owner will be set on the device later, so postpone
             // disabling escrow token for now.
-            if (!mDevicePolicyManager.isDeviceProvisioned()) {
+            if (!dpm.isDeviceProvisioned()) {
                 Slog.i(TAG, "Postpone disabling escrow tokens until device is provisioned");
                 return;
             }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b40e709..5a2434b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -19777,14 +19777,16 @@
 
         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
-                | Intent.FLAG_RECEIVER_FOREGROUND);
+                | Intent.FLAG_RECEIVER_FOREGROUND
+                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
                 AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
                 UserHandle.USER_ALL);
         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
-                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
             if (initLocale || !mProcessesReady) {
                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
             }
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index cba694c..d1275bb 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -65,16 +65,6 @@
     private static final boolean DEBUG = false;
 
     /**
-     * Night display ~= 3400 K.
-     */
-    private static final float[] MATRIX_NIGHT = new float[] {
-        1,      0,      0, 0,
-        0, 0.754f,      0, 0,
-        0,      0, 0.516f, 0,
-        0,      0,      0, 1
-    };
-
-    /**
      * The transition time, in milliseconds, for Night Display to turn on/off.
      */
     private static final long TRANSITION_DURATION = 3000L;
@@ -112,13 +102,34 @@
                     if (enabled) {
                         dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, MATRIX_IDENTITY);
                     } else if (mController != null && mController.isActivated()) {
-                        dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, MATRIX_NIGHT);
+                        setMatrix(mController.getColorTemperature(), mMatrixNight);
+                        dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, mMatrixNight);
                     }
                 }
             });
         }
     };
 
+    private float[] mMatrixNight = new float[16];
+
+    /**
+     *  These coefficients were generated by an LLS quadratic regression fitted to the
+     *  overdetermined system based on experimental readings (and subsequent conversion from xy
+     *  chromaticity coordinates to gamma-corrected RGB values): { (temperature, R, G, B) } ->
+     *  { (7304, 1.0, 1.0, 1.0), (4082, 1.0, 0.857, 0.719), (2850, 1.0, .754, .516),
+     *  (2596, 1.0, 0.722, 0.454) }. The 3x3 matrix is formatted like so:
+     *  <table>
+     *      <tr><td>R: a coefficient</td><td>G: a coefficient</td><td>B: a coefficient</td></tr>
+     *      <tr><td>R: b coefficient</td><td>G: b coefficient</td><td>B: b coefficient</td></tr>
+     *      <tr><td>R: y-intercept</td><td>G: y-intercept</td><td>B: y-intercept</td></tr>
+     *  </table>
+     */
+    private static final float[] mColorTempCoefficients = new float[] {
+            0.0f, -0.00000000962353339f, -0.0000000189359041f,
+            0.0f, 0.000153045476f, 0.000302412211f,
+            1.0f, 0.390782778f, -0.198650895f
+    };
+
     private int mCurrentUser = UserHandle.USER_NULL;
     private ContentObserver mUserSetupObserver;
     private boolean mBootCompleted;
@@ -232,6 +243,9 @@
         mController = new NightDisplayController(getContext(), mCurrentUser);
         mController.setListener(this);
 
+        // Prepare color transformation matrix.
+        setMatrix(mController.getColorTemperature(), mMatrixNight);
+
         // Initialize the current auto mode.
         onAutoModeChanged(mController.getAutoMode());
 
@@ -239,6 +253,9 @@
         if (mIsActivated == null) {
             onActivated(mController.isActivated());
         }
+
+        // Transition the screen to the current temperature.
+        applyTint(false);
     }
 
     private void tearDown() {
@@ -273,53 +290,7 @@
 
             mIsActivated = activated;
 
-            // Cancel the old animator if still running.
-            if (mColorMatrixAnimator != null) {
-                mColorMatrixAnimator.cancel();
-            }
-
-            // Don't do any color matrix change animations if we are ignoring them anyway.
-            if (mIgnoreAllColorMatrixChanges.get()) {
-                return;
-            }
-
-            final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
-            final float[] from = dtm.getColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY);
-            final float[] to = mIsActivated ? MATRIX_NIGHT : null;
-
-            mColorMatrixAnimator = ValueAnimator.ofObject(COLOR_MATRIX_EVALUATOR,
-                    from == null ? MATRIX_IDENTITY : from, to == null ? MATRIX_IDENTITY : to);
-            mColorMatrixAnimator.setDuration(TRANSITION_DURATION);
-            mColorMatrixAnimator.setInterpolator(AnimationUtils.loadInterpolator(
-                    getContext(), android.R.interpolator.fast_out_slow_in));
-            mColorMatrixAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator animator) {
-                    final float[] value = (float[]) animator.getAnimatedValue();
-                    dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, value);
-                }
-            });
-            mColorMatrixAnimator.addListener(new AnimatorListenerAdapter() {
-
-                private boolean mIsCancelled;
-
-                @Override
-                public void onAnimationCancel(Animator animator) {
-                    mIsCancelled = true;
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animator) {
-                    if (!mIsCancelled) {
-                        // Ensure final color matrix is set at the end of the animation. If the
-                        // animation is cancelled then don't set the final color matrix so the new
-                        // animator can pick up from where this one left off.
-                        dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, to);
-                    }
-                    mColorMatrixAnimator = null;
-                }
-            });
-            mColorMatrixAnimator.start();
+            applyTint(false);
         }
     }
 
@@ -361,6 +332,97 @@
         }
     }
 
+    @Override
+    public void onColorTemperatureChanged(int colorTemperature) {
+        setMatrix(colorTemperature, mMatrixNight);
+        applyTint(true);
+    }
+
+    /**
+     * Applies current color temperature matrix, or removes it if deactivated.
+     *
+     * @param immediate {@code true} skips transition animation
+     */
+    private void applyTint(boolean immediate) {
+        // Cancel the old animator if still running.
+        if (mColorMatrixAnimator != null) {
+            mColorMatrixAnimator.cancel();
+        }
+
+        // Don't do any color matrix change animations if we are ignoring them anyway.
+        if (mIgnoreAllColorMatrixChanges.get()) {
+            return;
+        }
+
+        final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
+        final float[] from = dtm.getColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY);
+        final float[] to = mIsActivated ? mMatrixNight : MATRIX_IDENTITY;
+
+        if (immediate) {
+            dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, to);
+        } else {
+            mColorMatrixAnimator = ValueAnimator.ofObject(COLOR_MATRIX_EVALUATOR,
+                    from == null ? MATRIX_IDENTITY : from, to);
+            mColorMatrixAnimator.setDuration(TRANSITION_DURATION);
+            mColorMatrixAnimator.setInterpolator(AnimationUtils.loadInterpolator(
+                    getContext(), android.R.interpolator.fast_out_slow_in));
+            mColorMatrixAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator animator) {
+                    final float[] value = (float[]) animator.getAnimatedValue();
+                    dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, value);
+                }
+            });
+            mColorMatrixAnimator.addListener(new AnimatorListenerAdapter() {
+
+                private boolean mIsCancelled;
+
+                @Override
+                public void onAnimationCancel(Animator animator) {
+                    mIsCancelled = true;
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animator) {
+                    if (!mIsCancelled) {
+                        // Ensure final color matrix is set at the end of the animation. If the
+                        // animation is cancelled then don't set the final color matrix so the new
+                        // animator can pick up from where this one left off.
+                        dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, to);
+                    }
+                    mColorMatrixAnimator = null;
+                }
+            });
+            mColorMatrixAnimator.start();
+        }
+    }
+
+    /**
+     * Set the color transformation {@code MATRIX_NIGHT} to the given color temperature.
+     *
+     * @param colorTemperature color temperature in Kelvin
+     * @param outTemp the 4x4 display transformation matrix for that color temperature
+     */
+    private void setMatrix(int colorTemperature, float[] outTemp) {
+        if (outTemp.length != 16) {
+            Slog.d(TAG, "The display transformation matrix must be 4x4");
+            return;
+        }
+
+        Matrix.setIdentityM(mMatrixNight, 0);
+
+        final float squareTemperature = colorTemperature * colorTemperature;
+        final float red = squareTemperature * mColorTempCoefficients[0]
+                + colorTemperature * mColorTempCoefficients[3] + mColorTempCoefficients[6];
+        final float green = squareTemperature * mColorTempCoefficients[1]
+                + colorTemperature * mColorTempCoefficients[4] + mColorTempCoefficients[7];
+        final float blue = squareTemperature * mColorTempCoefficients[2]
+                + colorTemperature * mColorTempCoefficients[5] + mColorTempCoefficients[8];
+        outTemp[0] = red;
+        outTemp[5] = green;
+        outTemp[10] = blue;
+    }
+
     private abstract class AutoMode implements NightDisplayController.Callback {
         public abstract void onStart();
         public abstract void onStop();
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 104c296..6d666e8 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -384,6 +384,7 @@
         mContext.unregisterReceiver(mTetherReceiver);
         mContext.unregisterReceiver(mPollReceiver);
         mContext.unregisterReceiver(mRemovedReceiver);
+        mContext.unregisterReceiver(mUserReceiver);
         mContext.unregisterReceiver(mShutdownReceiver);
 
         final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index c31369e..8f11436 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -145,10 +145,12 @@
         mHandler = new NotifierHandler(looper);
         mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
         mScreenOnIntent.addFlags(
-                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
+                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
         mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
         mScreenOffIntent.addFlags(
-                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
+                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
         mScreenBrightnessBoostIntent =
                 new Intent(PowerManager.ACTION_SCREEN_BRIGHTNESS_BOOST_CHANGED);
         mScreenBrightnessBoostIntent.addFlags(
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e6e0242..2727465 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -619,7 +619,6 @@
             startSensorService();
             traceLog.traceEnd();
         }, START_SENSOR_SERVICE);
-
     }
 
     /**
@@ -647,14 +646,6 @@
         traceBeginAndSlog("StartWebViewUpdateService");
         mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
         traceEnd();
-
-        // Start receiving calls from HIDL services. Start in in a separate thread
-        // because it need to connect to SensorManager.
-        SystemServerInitThreadPool.get().submit(() -> {
-            traceBeginAndSlog(START_HIDL_SERVICES);
-            startHidlServices();
-            traceEnd();
-        }, START_HIDL_SERVICES);
     }
 
     /**
@@ -813,6 +804,15 @@
             ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
             traceEnd();
 
+            // Start receiving calls from HIDL services. Start in in a separate thread
+            // because it need to connect to SensorManager. This have to start
+            // after START_SENSOR_SERVICE is done.
+            SystemServerInitThreadPool.get().submit(() -> {
+                traceBeginAndSlog(START_HIDL_SERVICES);
+                startHidlServices();
+                traceEnd();
+            }, START_HIDL_SERVICES);
+
             if (!disableVrManager) {
                 traceBeginAndSlog("StartVrManagerService");
                 mSystemServiceManager.startService(VrManagerService.class);
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 86f4a01..2729795 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -92,9 +92,6 @@
     // Cookie sent for usb hal death notification.
     private static final int USB_HAL_DEATH_COOKIE = 1000;
 
-    // Usb hal service name.
-    private static String sServiceName = "usb_hal";
-
     // Used as the key while sending the bundle to Main thread.
     private static final String PORT_INFO = "port_info";
 
@@ -499,16 +496,15 @@
             }
 
             try {
-                mProxy = IUsb.getService(sServiceName);
+                mProxy = IUsb.getService();
                 mProxy.linkToDeath(new DeathRecipient(pw), USB_HAL_DEATH_COOKIE);
                 mProxy.setCallback(mHALCallback);
                 mProxy.queryPortStatus();
             } catch (NoSuchElementException e) {
-                logAndPrintException(pw, sServiceName + " not found."
+                logAndPrintException(pw, "connectToProxy: usb hal service not found."
                         + " Did the service fail to start?", e);
             } catch (RemoteException e) {
-                logAndPrintException(pw, sServiceName
-                        + " connectToProxy: Service not responding", e);
+                logAndPrintException(pw, "connectToProxy: usb hal service not responding", e);
             }
         }
     }