Merge "Cleanup properties" into mnc-dev
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index 48167c8..bb761f0 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -93,12 +93,6 @@
 
     private static native long nCreateDisplayListCanvas();
 
-    public static void setProperty(String name, String value) {
-        nSetProperty(name, value);
-    }
-
-    private static native void nSetProperty(String name, String value);
-
     ///////////////////////////////////////////////////////////////////////////
     // Canvas management
     ///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 91e6d68..1fd7109 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -412,6 +413,13 @@
         nTrimMemory(level);
     }
 
+    public static void overrideProperty(@NonNull String name, @NonNull String value) {
+        if (name == null || value == null) {
+            throw new IllegalArgumentException("name and value must be non-null");
+        }
+        nOverrideProperty(name, value);
+    }
+
     public static void dumpProfileData(byte[] data, FileDescriptor fd) {
         nDumpProfileData(data, fd);
     }
@@ -510,6 +518,7 @@
 
     private static native void nDestroyHardwareResources(long nativeProxy);
     private static native void nTrimMemory(int level);
+    private static native void nOverrideProperty(String name, String value);
 
     private static native void nFence(long nativeProxy);
     private static native void nStopDrawing(long nativeProxy);
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 39449b0..bb8ef83 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -86,24 +86,6 @@
     renderer->finish();
 }
 
-static void android_view_DisplayListCanvas_setProperty(JNIEnv* env,
-        jobject clazz, jstring name, jstring value) {
-    if (!Caches::hasInstance()) {
-        ALOGW("can't set property, no Caches instance");
-        return;
-    }
-
-    if (name == NULL || value == NULL) {
-        ALOGW("can't set prop, null passed");
-    }
-
-    const char* nameCharArray = env->GetStringUTFChars(name, NULL);
-    const char* valueCharArray = env->GetStringUTFChars(value, NULL);
-    Caches::getInstance().setTempProperty(nameCharArray, valueCharArray);
-    env->ReleaseStringUTFChars(name, nameCharArray);
-    env->ReleaseStringUTFChars(name, valueCharArray);
-}
-
 // ----------------------------------------------------------------------------
 // Functor
 // ----------------------------------------------------------------------------
@@ -268,8 +250,6 @@
     { "nPrepare",           "(J)V",            (void*) android_view_DisplayListCanvas_prepare },
     { "nPrepareDirty",      "(JIIII)V",        (void*) android_view_DisplayListCanvas_prepareDirty },
     { "nFinish",            "(J)V",            (void*) android_view_DisplayListCanvas_finish },
-    { "nSetProperty",       "(Ljava/lang/String;Ljava/lang/String;)V",
-            (void*) android_view_DisplayListCanvas_setProperty },
 
     { "nCallDrawGLFunction", "(JJ)V",          (void*) android_view_DisplayListCanvas_callDrawGLFunction },
 
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 4ccbb41..5d5465b 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -388,6 +388,15 @@
     RenderProxy::trimMemory(level);
 }
 
+static void android_view_ThreadedRenderer_overrideProperty(JNIEnv* env, jobject clazz,
+        jstring name, jstring value) {
+    const char* nameCharArray = env->GetStringUTFChars(name, NULL);
+    const char* valueCharArray = env->GetStringUTFChars(value, NULL);
+    RenderProxy::overrideProperty(nameCharArray, valueCharArray);
+    env->ReleaseStringUTFChars(name, nameCharArray);
+    env->ReleaseStringUTFChars(name, valueCharArray);
+}
+
 static void android_view_ThreadedRenderer_fence(JNIEnv* env, jobject clazz,
         jlong proxyPtr) {
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -466,6 +475,7 @@
     { "nDetachSurfaceTexture", "(JJ)V", (void*) android_view_ThreadedRenderer_detachSurfaceTexture },
     { "nDestroyHardwareResources", "(J)V", (void*) android_view_ThreadedRenderer_destroyHardwareResources },
     { "nTrimMemory", "(I)V", (void*) android_view_ThreadedRenderer_trimMemory },
+    { "nOverrideProperty", "(Ljava/lang/String;Ljava/lang/String;)V",  (void*) android_view_ThreadedRenderer_overrideProperty },
     { "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence },
     { "nStopDrawing", "(J)V", (void*) android_view_ThreadedRenderer_stopDrawing },
     { "nNotifyFramePending", "(J)V", (void*) android_view_ThreadedRenderer_notifyFramePending },
diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk
index 836f868..8a4e609 100644
--- a/libs/hwui/Android.common.mk
+++ b/libs/hwui/Android.common.mk
@@ -63,6 +63,7 @@
     PixelBuffer.cpp \
     Program.cpp \
     ProgramCache.cpp \
+    Properties.cpp \
     RenderBufferCache.cpp \
     RenderNode.cpp \
     RenderProperties.cpp \
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index fd5a2ce..f75d6a0 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -57,14 +57,8 @@
     init();
     initFont();
     initConstraints();
-    initProperties();
     initStaticProperties();
     initExtensions();
-    initTempProperties();
-
-    mDebugLevel = readDebugLevel();
-    ALOGD_IF(mDebugLevel != kDebugDisabled,
-            "Enabling debug mode %d", mDebugLevel);
 }
 
 bool Caches::init() {
@@ -77,10 +71,6 @@
 
     mFunctorsCount = 0;
 
-    debugLayersUpdates = false;
-    debugOverdraw = false;
-    debugStencilClip = kStencilHide;
-
     patchCache.init();
 
     mInitialized = true;
@@ -124,66 +114,6 @@
     }
 }
 
-bool Caches::initProperties() {
-    bool prevDebugLayersUpdates = debugLayersUpdates;
-    bool prevDebugOverdraw = debugOverdraw;
-    StencilClipDebug prevDebugStencilClip = debugStencilClip;
-
-    char property[PROPERTY_VALUE_MAX];
-    if (property_get(PROPERTY_DEBUG_LAYERS_UPDATES, property, nullptr) > 0) {
-        INIT_LOGD("  Layers updates debug enabled: %s", property);
-        debugLayersUpdates = !strcmp(property, "true");
-    } else {
-        debugLayersUpdates = false;
-    }
-
-    debugOverdraw = false;
-    if (property_get(PROPERTY_DEBUG_OVERDRAW, property, nullptr) > 0) {
-        INIT_LOGD("  Overdraw debug enabled: %s", property);
-        if (!strcmp(property, "show")) {
-            debugOverdraw = true;
-            mOverdrawDebugColorSet = kColorSet_Default;
-        } else if (!strcmp(property, "show_deuteranomaly")) {
-            debugOverdraw = true;
-            mOverdrawDebugColorSet = kColorSet_Deuteranomaly;
-        }
-    }
-
-    // See Properties.h for valid values
-    if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, nullptr) > 0) {
-        INIT_LOGD("  Stencil clip debug enabled: %s", property);
-        if (!strcmp(property, "hide")) {
-            debugStencilClip = kStencilHide;
-        } else if (!strcmp(property, "highlight")) {
-            debugStencilClip = kStencilShowHighlight;
-        } else if (!strcmp(property, "region")) {
-            debugStencilClip = kStencilShowRegion;
-        }
-    } else {
-        debugStencilClip = kStencilHide;
-    }
-
-    if (property_get(PROPERTY_DISABLE_DRAW_DEFER, property, "false")) {
-        drawDeferDisabled = !strcasecmp(property, "true");
-        INIT_LOGD("  Draw defer %s", drawDeferDisabled ? "disabled" : "enabled");
-    } else {
-        drawDeferDisabled = false;
-        INIT_LOGD("  Draw defer enabled");
-    }
-
-    if (property_get(PROPERTY_DISABLE_DRAW_REORDER, property, "false")) {
-        drawReorderDisabled = !strcasecmp(property, "true");
-        INIT_LOGD("  Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled");
-    } else {
-        drawReorderDisabled = false;
-        INIT_LOGD("  Draw reorder enabled");
-    }
-
-    return (prevDebugLayersUpdates != debugLayersUpdates)
-            || (prevDebugOverdraw != debugOverdraw)
-            || (prevDebugStencilClip != debugStencilClip);
-}
-
 void Caches::terminate() {
     if (!mInitialized) return;
     mRegionMesh.release();
@@ -231,7 +161,9 @@
     };
     if (amount < 1) amount = 1;
     if (amount > 4) amount = 4;
-    return sOverdrawColors[mOverdrawDebugColorSet][amount - 1];
+
+    int overdrawColorIndex = static_cast<int>(Properties::overdrawColorSet);
+    return sOverdrawColors[overdrawColorIndex][amount - 1];
 }
 
 void Caches::dumpMemoryUsage() {
@@ -351,13 +283,13 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool discard) {
-    if (mExtensions.hasTiledRendering() && !debugOverdraw) {
+    if (mExtensions.hasTiledRendering() && !Properties::debugOverdraw) {
         glStartTilingQCOM(x, y, width, height, (discard ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM));
     }
 }
 
 void Caches::endTiling() {
-    if (mExtensions.hasTiledRendering() && !debugOverdraw) {
+    if (mExtensions.hasTiledRendering() && !Properties::debugOverdraw) {
         glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
     }
 }
@@ -395,44 +327,5 @@
 // Temporary Properties
 ///////////////////////////////////////////////////////////////////////////////
 
-void Caches::initTempProperties() {
-    propertyLightRadius = -1.0f;
-    propertyLightPosY = -1.0f;
-    propertyLightPosZ = -1.0f;
-    propertyAmbientRatio = -1.0f;
-    propertyAmbientShadowStrength = -1;
-    propertySpotShadowStrength = -1;
-}
-
-void Caches::setTempProperty(const char* name, const char* value) {
-    ALOGD("setting property %s to %s", name, value);
-    if (!strcmp(name, "ambientRatio")) {
-        propertyAmbientRatio = fmin(fmax(atof(value), 0.0), 10.0);
-        ALOGD("ambientRatio = %.2f", propertyAmbientRatio);
-        return;
-    } else if (!strcmp(name, "lightRadius")) {
-        propertyLightRadius = fmin(fmax(atof(value), 0.0), 3000.0);
-        ALOGD("lightRadius = %.2f", propertyLightRadius);
-        return;
-    } else if (!strcmp(name, "lightPosY")) {
-        propertyLightPosY = fmin(fmax(atof(value), 0.0), 3000.0);
-        ALOGD("lightPos Y = %.2f", propertyLightPosY);
-        return;
-    } else if (!strcmp(name, "lightPosZ")) {
-        propertyLightPosZ = fmin(fmax(atof(value), 0.0), 3000.0);
-        ALOGD("lightPos Z = %.2f", propertyLightPosZ);
-        return;
-    } else if (!strcmp(name, "ambientShadowStrength")) {
-        propertyAmbientShadowStrength = atoi(value);
-        ALOGD("ambient shadow strength = 0x%x out of 0xff", propertyAmbientShadowStrength);
-        return;
-    } else if (!strcmp(name, "spotShadowStrength")) {
-        propertySpotShadowStrength = atoi(value);
-        ALOGD("spot shadow strength = 0x%x out of 0xff", propertySpotShadowStrength);
-        return;
-    }
-    ALOGD("    failed");
-}
-
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 8aea8ff..804f609 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -80,7 +80,7 @@
     }
 
     static bool hasInstance() {
-        return sInstance != 0;
+        return sInstance != nullptr;
     }
 private:
     Caches(RenderState& renderState);
@@ -99,11 +99,6 @@
     bool init();
 
     /**
-     * Initialize global system properties.
-     */
-    bool initProperties();
-
-    /**
      * Flush the cache.
      *
      * @param mode Indicates how much of the cache should be flushed
@@ -117,14 +112,6 @@
     void terminate();
 
     /**
-     * Indicates whether the renderer is in debug mode.
-     * This debug mode provides limited information to app developers.
-     */
-    DebugLevel getDebugLevel() const {
-        return mDebugLevel;
-    }
-
-    /**
      * Returns a non-premultiplied ARGB color for the specified
      * amount of overdraw (1 for 1x, 2 for 2x, etc.)
      */
@@ -162,22 +149,9 @@
     void registerFunctors(uint32_t functorCount);
     void unregisterFunctors(uint32_t functorCount);
 
-    bool drawDeferDisabled;
-    bool drawReorderDisabled;
-
     // Misc
     GLint maxTextureSize;
 
-    // Debugging
-    bool debugLayersUpdates;
-    bool debugOverdraw;
-
-    enum StencilClipDebug {
-        kStencilHide,
-        kStencilShowHighlight,
-        kStencilShowRegion
-    };
-    StencilClipDebug debugStencilClip;
 private:
     // Declared before gradientCache and programCache which need this to initialize.
     // TODO: cleanup / move elsewhere
@@ -207,17 +181,6 @@
     PFNGLPUSHGROUPMARKEREXTPROC startMark;
     PFNGLPOPGROUPMARKEREXTPROC endMark;
 
-    // TEMPORARY properties
-    void initTempProperties();
-    void setTempProperty(const char* name, const char* value);
-
-    float propertyLightRadius;
-    float propertyLightPosY;
-    float propertyLightPosZ;
-    float propertyAmbientRatio;
-    int propertyAmbientShadowStrength;
-    int propertySpotShadowStrength;
-
     void setProgram(const ProgramDescription& description);
     void setProgram(Program* program);
 
@@ -227,10 +190,6 @@
     TextureState& textureState() { return *mTextureState; }
 
 private:
-    enum OverdrawColorSet {
-        kColorSet_Default = 0,
-        kColorSet_Deuteranomaly
-    };
 
     void initFont();
     void initExtensions();
@@ -249,13 +208,10 @@
     mutable Mutex mGarbageLock;
     Vector<Layer*> mLayerGarbage;
 
-    DebugLevel mDebugLevel;
     bool mInitialized;
 
     uint32_t mFunctorsCount;
 
-    OverdrawColorSet mOverdrawDebugColorSet;
-
     // TODO: move below to RenderState
     PixelBufferState* mPixelBufferState = nullptr;
     TextureState* mTextureState = nullptr;
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
index dd6af03..6fcf958 100644
--- a/libs/hwui/DeferredDisplayList.cpp
+++ b/libs/hwui/DeferredDisplayList.cpp
@@ -28,6 +28,7 @@
 #include "DeferredDisplayList.h"
 #include "DisplayListOp.h"
 #include "OpenGLRenderer.h"
+#include "Properties.h"
 #include "utils/MathUtils.h"
 
 #if DEBUG_DEFER
@@ -502,7 +503,7 @@
         resetBatchingState();
     }
 
-    if (CC_UNLIKELY(renderer.getCaches().drawReorderDisabled)) {
+    if (CC_UNLIKELY(Properties::drawReorderDisabled)) {
         // TODO: elegant way to reuse batches?
         DrawBatch* b = new DrawBatch(deferInfo);
         b->add(op, state, deferInfo.opaqueOverBounds);
diff --git a/libs/hwui/DrawProfiler.cpp b/libs/hwui/DrawProfiler.cpp
index ecde5ff..7addef9 100644
--- a/libs/hwui/DrawProfiler.cpp
+++ b/libs/hwui/DrawProfiler.cpp
@@ -18,12 +18,11 @@
 #include <cutils/compiler.h>
 
 #include "OpenGLRenderer.h"
-#include "Properties.h"
 
 #define DEFAULT_MAX_FRAMES 128
 
-#define RETURN_IF_PROFILING_DISABLED() if (CC_LIKELY(mType == kNone)) return
-#define RETURN_IF_DISABLED() if (CC_LIKELY(mType == kNone && !mShowDirtyRegions)) return
+#define RETURN_IF_PROFILING_DISABLED() if (CC_LIKELY(mType == ProfileType::None)) return
+#define RETURN_IF_DISABLED() if (CC_LIKELY(mType == ProfileType::None && !mShowDirtyRegions)) return
 
 #define NANOS_TO_MILLIS_FLOAT(nanos) ((nanos) * 0.000001f)
 
@@ -56,18 +55,7 @@
     return (int) (dp * density + 0.5f);
 }
 
-DrawProfiler::DrawProfiler()
-        : mType(kNone)
-        , mDensity(0)
-        , mData(nullptr)
-        , mDataSize(0)
-        , mCurrentFrame(-1)
-        , mPreviousTime(0)
-        , mVerticalUnit(0)
-        , mHorizontalUnit(0)
-        , mThresholdStroke(0)
-        , mShowDirtyRegions(false)
-        , mFlashToggle(false) {
+DrawProfiler::DrawProfiler() {
     setDensity(1);
 }
 
@@ -135,7 +123,7 @@
         }
     }
 
-    if (mType == kBars) {
+    if (mType == ProfileType::Bars) {
         prepareShapes(canvas->getViewportHeight());
         drawGraph(canvas);
         drawCurrentFrame(canvas);
@@ -217,32 +205,20 @@
     canvas->drawLines(pts, 4, &paint);
 }
 
-DrawProfiler::ProfileType DrawProfiler::loadRequestedProfileType() {
-    ProfileType type = kNone;
-    char buf[PROPERTY_VALUE_MAX] = {'\0',};
-    if (property_get(PROPERTY_PROFILE, buf, "") > 0) {
-        if (!strcmp(buf, PROPERTY_PROFILE_VISUALIZE_BARS)) {
-            type = kBars;
-        } else if (!strcmp(buf, "true")) {
-            type = kConsole;
-        }
-    }
-    return type;
-}
-
-bool DrawProfiler::loadSystemProperties() {
+bool DrawProfiler::consumeProperties() {
     bool changed = false;
-    ProfileType newType = loadRequestedProfileType();
+    ProfileType newType = Properties::getProfileType();
     if (newType != mType) {
         mType = newType;
-        if (mType == kNone) {
+        if (mType == ProfileType::None) {
             destroyData();
         } else {
             createData();
         }
         changed = true;
     }
-    bool showDirty = property_get_bool(PROPERTY_DEBUG_SHOW_DIRTY_REGIONS, false);
+
+    bool showDirty = Properties::showDirtyRegions;
     if (showDirty != mShowDirtyRegions) {
         mShowDirtyRegions = showDirty;
         changed = true;
diff --git a/libs/hwui/DrawProfiler.h b/libs/hwui/DrawProfiler.h
index de64088..ef6101c 100644
--- a/libs/hwui/DrawProfiler.h
+++ b/libs/hwui/DrawProfiler.h
@@ -16,9 +16,11 @@
 #ifndef DRAWPROFILER_H
 #define DRAWPROFILER_H
 
-#include <utils/Timers.h>
+#include "Properties.h"
 #include "Rect.h"
 
+#include <utils/Timers.h>
+
 namespace android {
 namespace uirenderer {
 
@@ -29,7 +31,7 @@
     DrawProfiler();
     ~DrawProfiler();
 
-    bool loadSystemProperties();
+    bool consumeProperties();
     void setDensity(float density);
 
     void startFrame(nsecs_t recordDurationNanos = 0);
@@ -43,12 +45,6 @@
     void dumpData(int fd);
 
 private:
-    enum ProfileType {
-        kNone,
-        kConsole,
-        kBars,
-    };
-
     typedef struct {
         float record;
         float prepare;
@@ -65,20 +61,18 @@
     void drawCurrentFrame(OpenGLRenderer* canvas);
     void drawThreshold(OpenGLRenderer* canvas);
 
-    ProfileType loadRequestedProfileType();
+    ProfileType mType = ProfileType::None;
+    float mDensity = 0;
 
-    ProfileType mType;
-    float mDensity;
+    FrameTimingData* mData = nullptr;
+    int mDataSize = 0;
 
-    FrameTimingData* mData;
-    int mDataSize;
+    int mCurrentFrame = -1;
+    nsecs_t mPreviousTime = 0;
 
-    int mCurrentFrame;
-    nsecs_t mPreviousTime;
-
-    int mVerticalUnit;
-    int mHorizontalUnit;
-    int mThresholdStroke;
+    int mVerticalUnit = 0;
+    int mHorizontalUnit = 0;
+    int mThresholdStroke = 0;
 
     /*
      * mRects represents an array of rect shapes, divided into NUM_ELEMENTS
@@ -87,11 +81,11 @@
      * OpenGLRenderer:drawRects() that makes up all the FrameTimingData:record
      * information.
      */
-    float** mRects;
+    float** mRects = nullptr;
 
-    bool mShowDirtyRegions;
+    bool mShowDirtyRegions = false;
     SkRect mDirtyRegion;
-    bool mFlashToggle;
+    bool mFlashToggle = false;
 };
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 9ca6bc6..e25f81e 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -588,8 +588,8 @@
 
     // Enable debug highlight when what we're about to draw is tested against
     // the stencil buffer and if stencil highlight debugging is on
-    mDescription.hasDebugHighlight = !mCaches.debugOverdraw
-            && mCaches.debugStencilClip == Caches::kStencilShowHighlight
+    mDescription.hasDebugHighlight = !Properties::debugOverdraw
+            && Properties::debugStencilClip == StencilClipDebug::ShowHighlight
             && mRenderState.stencil().isTestEnabled();
 
     // serialize shader info into ShaderData
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 7fc31b8..09674f7 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -245,7 +245,7 @@
 #if DEBUG_MEMORY_USAGE
         mCaches.dumpMemoryUsage();
 #else
-        if (mCaches.getDebugLevel() & kDebugMemory) {
+        if (Properties::debugLevel & kDebugMemory) {
             mCaches.dumpMemoryUsage();
         }
 #endif
@@ -339,7 +339,7 @@
 }
 
 void OpenGLRenderer::renderOverdraw() {
-    if (mCaches.debugOverdraw && getTargetFbo() == 0) {
+    if (Properties::debugOverdraw && getTargetFbo() == 0) {
         const Rect* clip = &mTilingClip;
 
         mRenderState.scissor().setEnabled(true);
@@ -381,7 +381,7 @@
             debugOverdraw(false, false);
         }
 
-        if (CC_UNLIKELY(inFrame || mCaches.drawDeferDisabled)) {
+        if (CC_UNLIKELY(inFrame || Properties::drawDeferDisabled)) {
             layer->render(*this);
         } else {
             layer->defer(*this);
@@ -392,7 +392,7 @@
             startTilingCurrentClip();
         }
 
-        layer->debugDrawUpdate = mCaches.debugLayersUpdates;
+        layer->debugDrawUpdate = Properties::debugLayersUpdates;
         layer->hasDrawnSinceUpdate = false;
 
         return true;
@@ -407,7 +407,7 @@
     // in the layer updates list which will be cleared by flushLayers().
     int count = mLayerUpdates.size();
     if (count > 0) {
-        if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
+        if (CC_UNLIKELY(Properties::drawDeferDisabled)) {
             startMark("Layer Updates");
         } else {
             startMark("Defer Layer Updates");
@@ -419,7 +419,7 @@
             updateLayer(layer, false);
         }
 
-        if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
+        if (CC_UNLIKELY(Properties::drawDeferDisabled)) {
             mLayerUpdates.clear();
             mRenderState.bindFramebuffer(getTargetFbo());
         }
@@ -883,13 +883,13 @@
  * operations are correctly counted twice for overdraw. NOTE: assumes composeLayerRegion only used
  * by saveLayer's restore
  */
-#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) {                             \
-        DRAW_COMMAND;                                                            \
-        if (CC_UNLIKELY(mCaches.debugOverdraw && getTargetFbo() == 0 && COND)) { \
-            glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);                 \
-            DRAW_COMMAND;                                                        \
-            glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);                     \
-        }                                                                        \
+#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \
+        DRAW_COMMAND; \
+        if (CC_UNLIKELY(Properties::debugOverdraw && getTargetFbo() == 0 && COND)) { \
+            glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \
+            DRAW_COMMAND; \
+            glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \
+        } \
     }
 
 #define DRAW_DOUBLE_STENCIL(DRAW_COMMAND) DRAW_DOUBLE_STENCIL_IF(true, DRAW_COMMAND)
@@ -1324,7 +1324,7 @@
 }
 
 void OpenGLRenderer::setStencilFromClip() {
-    if (!mCaches.debugOverdraw) {
+    if (!Properties::debugOverdraw) {
         if (!currentSnapshot()->clipIsSimple()) {
             int incrementThreshold;
             EVENT_LOGD("setStencilFromClip - enabling");
@@ -1383,8 +1383,8 @@
             // Draw the region used to generate the stencil if the appropriate debug
             // mode is enabled
             // TODO: Implement for rectangle list clip areas
-            if (mCaches.debugStencilClip == Caches::kStencilShowRegion &&
-                    !clipArea.isRectangleList()) {
+            if (Properties::debugStencilClip == StencilClipDebug::ShowRegion
+                    && !clipArea.isRectangleList()) {
                 paint.setColor(0x7f0000ff);
                 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
                 drawRegionRects(currentSnapshot()->getClipRegion(), paint);
@@ -1469,7 +1469,7 @@
     if (renderNode && renderNode->isRenderable()) {
         // compute 3d ordering
         renderNode->computeOrdering();
-        if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
+        if (CC_UNLIKELY(Properties::drawDeferDisabled)) {
             startFrame();
             ReplayStateStruct replayStruct(*this, dirty, replayFlags);
             renderNode->replay(replayStruct, 0);
@@ -1478,7 +1478,7 @@
 
         // Don't avoid overdraw when visualizing, since that makes it harder to
         // debug where it's coming from, and when the problem occurs.
-        bool avoidOverdraw = !mCaches.debugOverdraw;
+        bool avoidOverdraw = !Properties::debugOverdraw;
         DeferredDisplayList deferredList(mState.currentClipRect(), avoidOverdraw);
         DeferStateStruct deferStruct(deferredList, *this, replayFlags);
         renderNode->defer(deferStruct, 0);
@@ -2452,8 +2452,8 @@
 
     // The caller has made sure casterAlpha > 0.
     float ambientShadowAlpha = mAmbientShadowAlpha;
-    if (CC_UNLIKELY(mCaches.propertyAmbientShadowStrength >= 0)) {
-        ambientShadowAlpha = mCaches.propertyAmbientShadowStrength;
+    if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) {
+        ambientShadowAlpha = Properties::overrideAmbientShadowStrength;
     }
     if (ambientShadowVertexBuffer && ambientShadowAlpha > 0) {
         paint.setARGB(casterAlpha * ambientShadowAlpha, 0, 0, 0);
@@ -2461,8 +2461,8 @@
     }
 
     float spotShadowAlpha = mSpotShadowAlpha;
-    if (CC_UNLIKELY(mCaches.propertySpotShadowStrength >= 0)) {
-        spotShadowAlpha = mCaches.propertySpotShadowStrength;
+    if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) {
+        spotShadowAlpha = Properties::overrideSpotShadowStrength;
     }
     if (spotShadowVertexBuffer && spotShadowAlpha > 0) {
         paint.setARGB(casterAlpha * spotShadowAlpha, 0, 0, 0);
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index bdb44a6..74964f6 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -153,7 +153,7 @@
     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
     mMaxTextureSize = maxTextureSize;
 
-    mDebugEnabled = readDebugLevel() & kDebugCaches;
+    mDebugEnabled = Properties::debugLevel & kDebugCaches;
 }
 
 PathCache::~PathCache() {
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
new file mode 100644
index 0000000..fd32b6f
--- /dev/null
+++ b/libs/hwui/Properties.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+#include "Properties.h"
+
+#include "Debug.h"
+
+#include <cmath>
+#include <cutils/log.h>
+
+namespace android {
+namespace uirenderer {
+
+bool Properties::drawDeferDisabled = false;
+bool Properties::drawReorderDisabled = false;
+bool Properties::debugLayersUpdates = false;
+bool Properties::debugOverdraw = false;
+bool Properties::showDirtyRegions = false;
+
+DebugLevel Properties::debugLevel = kDebugDisabled;
+OverdrawColorSet Properties::overdrawColorSet = OverdrawColorSet::Default;
+StencilClipDebug Properties::debugStencilClip = StencilClipDebug::Hide;
+
+float Properties::overrideLightRadius = -1.0f;
+float Properties::overrideLightPosY = -1.0f;
+float Properties::overrideLightPosZ = -1.0f;
+float Properties::overrideAmbientRatio = -1.0f;
+int Properties::overrideAmbientShadowStrength = -1;
+int Properties::overrideSpotShadowStrength = -1;
+
+ProfileType Properties::sProfileType = ProfileType::None;
+bool Properties::sDisableProfileBars = false;
+
+bool Properties::load() {
+    char property[PROPERTY_VALUE_MAX];
+    bool prevDebugLayersUpdates = debugLayersUpdates;
+    bool prevDebugOverdraw = debugOverdraw;
+    StencilClipDebug prevDebugStencilClip = debugStencilClip;
+
+
+    debugOverdraw = false;
+    if (property_get(PROPERTY_DEBUG_OVERDRAW, property, nullptr) > 0) {
+        INIT_LOGD("  Overdraw debug enabled: %s", property);
+        if (!strcmp(property, "show")) {
+            debugOverdraw = true;
+            overdrawColorSet = OverdrawColorSet::Default;
+        } else if (!strcmp(property, "show_deuteranomaly")) {
+            debugOverdraw = true;
+            overdrawColorSet = OverdrawColorSet::Deuteranomaly;
+        }
+    }
+
+    // See Properties.h for valid values
+    if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, nullptr) > 0) {
+        INIT_LOGD("  Stencil clip debug enabled: %s", property);
+        if (!strcmp(property, "hide")) {
+            debugStencilClip = StencilClipDebug::Hide;
+        } else if (!strcmp(property, "highlight")) {
+            debugStencilClip = StencilClipDebug::ShowHighlight;
+        } else if (!strcmp(property, "region")) {
+            debugStencilClip = StencilClipDebug::ShowRegion;
+        }
+    } else {
+        debugStencilClip = StencilClipDebug::Hide;
+    }
+
+    sProfileType = ProfileType::None;
+    if (property_get(PROPERTY_PROFILE, property, "") > 0) {
+        if (!strcmp(property, PROPERTY_PROFILE_VISUALIZE_BARS)) {
+            sProfileType = ProfileType::Bars;
+        } else if (!strcmp(property, "true")) {
+            sProfileType = ProfileType::Console;
+        }
+    }
+
+    debugLayersUpdates = property_get_bool(PROPERTY_DEBUG_LAYERS_UPDATES, false);
+    INIT_LOGD("  Layers updates debug enabled: %d", debugLayersUpdates);
+
+    drawDeferDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_DEFER, false);
+    INIT_LOGD("  Draw defer %s", drawDeferDisabled ? "disabled" : "enabled");
+
+    drawReorderDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_REORDER, false);
+    INIT_LOGD("  Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled");
+
+    showDirtyRegions = property_get_bool(PROPERTY_DEBUG_SHOW_DIRTY_REGIONS, false);
+
+    debugLevel = kDebugDisabled;
+    if (property_get(PROPERTY_DEBUG, property, nullptr) > 0) {
+        debugLevel = (DebugLevel) atoi(property);
+    }
+
+    return (prevDebugLayersUpdates != debugLayersUpdates)
+            || (prevDebugOverdraw != debugOverdraw)
+            || (prevDebugStencilClip != debugStencilClip);
+}
+
+void Properties::overrideProperty(const char* name, const char* value) {
+    if (!strcmp(name, "disableProfileBars")) {
+        sDisableProfileBars = !strcmp(value, "true");
+        ALOGD("profile bars %s", sDisableProfileBars ? "disabled" : "enabled");
+        return;
+    } else if (!strcmp(name, "ambientRatio")) {
+        overrideAmbientRatio = fmin(fmax(atof(value), 0.0), 10.0);
+        ALOGD("ambientRatio = %.2f", overrideAmbientRatio);
+        return;
+    } else if (!strcmp(name, "lightRadius")) {
+        overrideLightRadius = fmin(fmax(atof(value), 0.0), 3000.0);
+        ALOGD("lightRadius = %.2f", overrideLightRadius);
+        return;
+    } else if (!strcmp(name, "lightPosY")) {
+        overrideLightPosY = fmin(fmax(atof(value), 0.0), 3000.0);
+        ALOGD("lightPos Y = %.2f", overrideLightPosY);
+        return;
+    } else if (!strcmp(name, "lightPosZ")) {
+        overrideLightPosZ = fmin(fmax(atof(value), 0.0), 3000.0);
+        ALOGD("lightPos Z = %.2f", overrideLightPosZ);
+        return;
+    } else if (!strcmp(name, "ambientShadowStrength")) {
+        overrideAmbientShadowStrength = atoi(value);
+        ALOGD("ambient shadow strength = 0x%x out of 0xff", overrideAmbientShadowStrength);
+        return;
+    } else if (!strcmp(name, "spotShadowStrength")) {
+        overrideSpotShadowStrength = atoi(value);
+        ALOGD("spot shadow strength = 0x%x out of 0xff", overrideSpotShadowStrength);
+        return;
+    }
+    ALOGD("failed overriding property %s to %s", name, value);
+}
+
+ProfileType Properties::getProfileType() {
+    if (CC_UNLIKELY(sDisableProfileBars && sProfileType == ProfileType::Bars))
+        return ProfileType::None;
+    return sProfileType;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index a0312e1..46fa940 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -19,12 +19,16 @@
 
 #include <cutils/properties.h>
 #include <stdlib.h>
+#include <utils/Singleton.h>
 
 /**
  * This file contains the list of system properties used to configure
  * the OpenGLRenderer.
  */
 
+namespace android {
+namespace uirenderer {
+
 ///////////////////////////////////////////////////////////////////////////////
 // Compile-time properties
 ///////////////////////////////////////////////////////////////////////////////
@@ -253,12 +257,61 @@
 // Converts a number of kilo-bytes into bytes
 #define KB(s) s * 1024
 
-static inline DebugLevel readDebugLevel() {
-    char property[PROPERTY_VALUE_MAX];
-    if (property_get(PROPERTY_DEBUG, property, nullptr) > 0) {
-        return (DebugLevel) atoi(property);
-    }
-    return kDebugDisabled;
-}
+enum class ProfileType {
+    None,
+    Console,
+    Bars
+};
+
+enum class OverdrawColorSet {
+    Default = 0,
+    Deuteranomaly
+};
+
+enum class StencilClipDebug {
+    Hide,
+    ShowHighlight,
+    ShowRegion
+};
+
+/**
+ * Renderthread-only singleton which manages several static rendering properties. Most of these
+ * are driven by system properties which are queried once at initialization, and again if init()
+ * is called.
+ */
+class Properties {
+public:
+    static bool load();
+
+    static bool drawDeferDisabled;
+    static bool drawReorderDisabled;
+    static bool debugLayersUpdates;
+    static bool debugOverdraw;
+    static bool showDirtyRegions;
+
+    static DebugLevel debugLevel;
+    static OverdrawColorSet overdrawColorSet;
+    static StencilClipDebug debugStencilClip;
+
+    // Override the value for a subset of properties in this class
+    static void overrideProperty(const char* name, const char* value);
+
+    static float overrideLightRadius;
+    static float overrideLightPosY;
+    static float overrideLightPosZ;
+    static float overrideAmbientRatio;
+    static int overrideAmbientShadowStrength;
+    static int overrideSpotShadowStrength;
+
+    static ProfileType getProfileType();
+
+private:
+    static ProfileType sProfileType;
+    static bool sDisableProfileBars;
+
+}; // class Caches
+
+}; // namespace uirenderer
+}; // namespace android
 
 #endif // ANDROID_HWUI_PROPERTIES_H
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index 30d3f41..fb28531 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -20,11 +20,13 @@
 #include <math.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
+#include <utils/Vector.h>
 
 #include "AmbientShadow.h"
-#include "Caches.h"
+#include "Properties.h"
 #include "ShadowTessellator.h"
 #include "SpotShadow.h"
+#include "Vector.h"
 
 namespace android {
 namespace uirenderer {
@@ -40,9 +42,8 @@
     float heightFactor = 1.0f / 128;
     const float geomFactor = 64;
 
-    Caches& caches = Caches::getInstance();
-    if (CC_UNLIKELY(caches.propertyAmbientRatio > 0.0f)) {
-        heightFactor *= caches.propertyAmbientRatio;
+    if (CC_UNLIKELY(Properties::overrideAmbientRatio > 0.0f)) {
+        heightFactor *= Properties::overrideAmbientRatio;
     }
 
     Rect ambientShadowBounds(casterBounds);
@@ -66,14 +67,12 @@
         const Rect& casterBounds, const Rect& localClip, VertexBuffer& shadowVertexBuffer) {
     ATRACE_CALL();
 
-    Caches& caches = Caches::getInstance();
-
     Vector3 adjustedLightCenter(lightCenter);
-    if (CC_UNLIKELY(caches.propertyLightPosY > 0)) {
-        adjustedLightCenter.y = - caches.propertyLightPosY; // negated since this shifts up
+    if (CC_UNLIKELY(Properties::overrideLightPosY > 0)) {
+        adjustedLightCenter.y = - Properties::overrideLightPosY; // negated since this shifts up
     }
-    if (CC_UNLIKELY(caches.propertyLightPosZ > 0)) {
-        adjustedLightCenter.z = caches.propertyLightPosZ;
+    if (CC_UNLIKELY(Properties::overrideLightPosZ > 0)) {
+        adjustedLightCenter.z = Properties::overrideLightPosZ;
     }
 
 #if DEBUG_SHADOW
@@ -87,8 +86,8 @@
     reverseReceiverTransform.loadInverse(receiverTransform);
     reverseReceiverTransform.mapPoint3d(adjustedLightCenter);
 
-    if (CC_UNLIKELY(caches.propertyLightRadius > 0)) {
-        lightRadius = caches.propertyLightRadius;
+    if (CC_UNLIKELY(Properties::overrideLightRadius > 0)) {
+        lightRadius = Properties::overrideLightRadius;
     }
 
     // Now light and caster are both in local space, we will check whether
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index 7edb9fb..fc173f7 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -311,7 +311,7 @@
 
     mCache.setOnEntryRemovedListener(&mBufferRemovedListener);
     mShadowCache.setOnEntryRemovedListener(&mBufferPairRemovedListener);
-    mDebugEnabled = readDebugLevel() & kDebugCaches;
+    mDebugEnabled = Properties::debugLevel & kDebugCaches;
 }
 
 TessellationCache::~TessellationCache() {
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index c2e88f3..8b1d4cb 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -123,7 +123,7 @@
 
 void TextDropShadowCache::init() {
     mCache.setOnEntryRemovedListener(this);
-    mDebugEnabled = readDebugLevel() & kDebugMoreCaches;
+    mDebugEnabled = Properties::debugLevel & kDebugMoreCaches;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index b911a0f..e59688c 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -66,7 +66,7 @@
     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
     INIT_LOGD("    Maximum texture dimension is %d pixels", mMaxTextureSize);
 
-    mDebugEnabled = readDebugLevel() & kDebugCaches;
+    mDebugEnabled = Properties::debugLevel & kDebugCaches;
 }
 
 TextureCache::~TextureCache() {
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 7b44d6d..e54fa5a 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -154,7 +154,7 @@
 }
 
 void RenderState::debugOverdraw(bool enable, bool clear) {
-    if (mCaches->debugOverdraw && mFramebuffer == 0) {
+    if (Properties::debugOverdraw && mFramebuffer == 0) {
         if (clear) {
             scissor().setEnabled(false);
             stencil().clear();
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index a7bfb84..c643e1d 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -112,9 +112,9 @@
 CREATE_BRIDGE1(loadSystemProperties, CanvasContext* context) {
     bool needsRedraw = false;
     if (Caches::hasInstance()) {
-        needsRedraw = Caches::getInstance().initProperties();
+        needsRedraw = Properties::load();
     }
-    if (args->context->profiler().loadSystemProperties()) {
+    if (args->context->profiler().consumeProperties()) {
         needsRedraw = true;
     }
     return (void*) needsRedraw;
@@ -135,7 +135,7 @@
     SETUP_TASK(setName);
     args->context = mContext;
     args->name = name;
-    postAndWait(task);
+    postAndWait(task); // block since name/value pointers owned by caller
 }
 
 CREATE_BRIDGE2(initialize, CanvasContext* context, ANativeWindow* window) {
@@ -331,7 +331,7 @@
     post(task);
 }
 
-CREATE_BRIDGE2(timMemory, RenderThread* thread, int level) {
+CREATE_BRIDGE2(trimMemory, RenderThread* thread, int level) {
     CanvasContext::trimMemory(*args->thread, args->level);
     return nullptr;
 }
@@ -340,13 +340,26 @@
     // Avoid creating a RenderThread to do a trimMemory.
     if (RenderThread::hasInstance()) {
         RenderThread& thread = RenderThread::getInstance();
-        SETUP_TASK(timMemory);
+        SETUP_TASK(trimMemory);
         args->thread = &thread;
         args->level = level;
         thread.queue(task);
     }
 }
 
+CREATE_BRIDGE2(overrideProperty, const char* name, const char* value) {
+    Properties::overrideProperty(args->name, args->value);
+    return nullptr;
+}
+
+void RenderProxy::overrideProperty(const char* name, const char* value) {
+    RenderThread& thread = RenderThread::getInstance();
+    SETUP_TASK(overrideProperty);
+    args->name = name;
+    args->value = value;
+    staticPostAndWait(task); // expensive, but block here since name/value pointers owned by caller
+}
+
 CREATE_BRIDGE0(fence) {
     // Intentionally empty
     return nullptr;
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index a1dbc7d..31456cd 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -90,6 +90,7 @@
 
     ANDROID_API void destroyHardwareResources();
     ANDROID_API static void trimMemory(int level);
+    ANDROID_API static void overrideProperty(const char* name, const char* value);
 
     ANDROID_API void fence();
     ANDROID_API void stopDrawing();
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 3ac2976..64075f1 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -144,6 +144,7 @@
         , mFrameCallbackTask(nullptr)
         , mRenderState(nullptr)
         , mEglManager(nullptr) {
+    Properties::load();
     mFrameCallbackTask = new DispatchFrameCallbacks(this);
     mLooper = new Looper(false);
     run("RenderThread");
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 1001feb..ad97f91 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -39,7 +39,6 @@
 import com.android.systemui.recents.misc.DebugTrigger;
 import com.android.systemui.recents.misc.ReferenceCountedTrigger;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.RecentsTaskLoadPlan;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
@@ -392,15 +391,6 @@
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
         registerReceiver(mSystemBroadcastReceiver, filter);
-
-        // Private API calls to make the shadows look better
-        try {
-            Utilities.setShadowProperty("ambientRatio", String.valueOf(1.5f));
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-        } catch (InvocationTargetException e) {
-            e.printStackTrace();
-        }
     }
 
     /** Inflates the debug overlay if debug mode is enabled. */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
index 84544ff..e810410 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
@@ -22,27 +22,11 @@
 import android.graphics.Rect;
 import android.view.View;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 
 /* Common code */
 public class Utilities {
 
-    // Reflection methods for altering shadows
-    private static Method sPropertyMethod;
-    static {
-        try {
-            Class<?> c = Class.forName("android.view.DisplayListCanvas");
-            sPropertyMethod = c.getDeclaredMethod("setProperty", String.class, String.class);
-            if (!sPropertyMethod.isAccessible()) sPropertyMethod.setAccessible(true);
-        } catch (ClassNotFoundException e) {
-            e.printStackTrace();
-        } catch (NoSuchMethodException e) {
-            e.printStackTrace();
-        }
-    }
-
     /** Scales a rect about its centroid */
     public static void scaleRectAboutCenter(Rect r, float scale) {
         if (scale != 1.0f) {
@@ -163,12 +147,6 @@
                     (1f - overlayAlpha) * Color.blue(overlayColor)));
     }
 
-    /** Sets some private shadow properties. */
-    public static void setShadowProperty(String property, String value)
-            throws IllegalAccessException, InvocationTargetException {
-        sPropertyMethod.invoke(null, property, value);
-    }
-
     /**
      * Cancels an animation ensuring that if it has listeners, onCancel and onEnd
      * are not called.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index a1d66d4..4e46854 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -76,6 +76,7 @@
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.ThreadedRenderer;
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
@@ -857,6 +858,12 @@
         // listen for USER_SETUP_COMPLETE setting (per-user)
         resetUserSetupObserver();
 
+        // disable profiling bars, since they overlap and clutter the output on app windows
+        ThreadedRenderer.overrideProperty("disableProfileBars", "true");
+
+        // Private API call to make the shadows look better for Recents
+        ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
+
         return mStatusBarView;
     }