diff --git a/src/com/android/settings/SummaryPreference.java b/src/com/android/settings/SummaryPreference.java
index 23965ee..dbe036a 100644
--- a/src/com/android/settings/SummaryPreference.java
+++ b/src/com/android/settings/SummaryPreference.java
@@ -20,10 +20,9 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
+import android.widget.ProgressBar;
 import android.widget.TextView;
 
-import com.android.settings.widget.LinearColorBar;
-
 /**
  * Provides a summary of a setting page in a preference.  Such as memory or data usage.
  */
@@ -33,8 +32,6 @@
     private String mAmount;
     private String mUnits;
 
-    private int mLeft, mMiddle, mRight;
-    private boolean mColorsSet = false;
     private boolean mChartEnabled = true;
     private float mLeftRatio, mMiddleRatio, mRightRatio;
     private String mStartLabel;
@@ -81,26 +78,17 @@
         notifyChanged();
     }
 
-    public void setColors(int left, int middle, int right) {
-        mLeft = left;
-        mMiddle = middle;
-        mRight = right;
-        mColorsSet = true;
-        notifyChanged();
-    }
-
     @Override
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
 
-        final LinearColorBar colorBar = holder.itemView.findViewById(R.id.color_bar);
+        final ProgressBar colorBar = holder.itemView.findViewById(R.id.color_bar);
 
         if (mChartEnabled) {
             colorBar.setVisibility(View.VISIBLE);
-            colorBar.setRatios(mLeftRatio, mMiddleRatio, mRightRatio);
-            if (mColorsSet) {
-                colorBar.setColors(mLeft, mMiddle, mRight);
-            }
+            int progress = (int) (mLeftRatio * 100);
+            colorBar.setProgress(progress);
+            colorBar.setSecondaryProgress(progress + (int) (mMiddleRatio * 100));
         } else {
             colorBar.setVisibility(View.GONE);
         }
diff --git a/src/com/android/settings/applications/RunningProcessesView.java b/src/com/android/settings/applications/RunningProcessesView.java
index 650f56c..d714c5f 100644
--- a/src/com/android/settings/applications/RunningProcessesView.java
+++ b/src/com/android/settings/applications/RunningProcessesView.java
@@ -20,6 +20,8 @@
 import android.app.Dialog;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -36,6 +38,7 @@
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.ListView;
+import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import com.android.internal.util.MemInfoReader;
@@ -43,7 +46,6 @@
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
 import com.android.settings.core.SubSettingLauncher;
-import com.android.settings.widget.LinearColorBar;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -75,7 +77,7 @@
     ListView mListView;
     View mHeader;
     ServiceListAdapter mAdapter;
-    LinearColorBar mColorBar;
+    ProgressBar mColorBar;
     TextView mBackgroundProcessPrefix;
     TextView mAppsProcessPrefix;
     TextView mForegroundProcessPrefix;
@@ -385,9 +387,9 @@
                         Formatter.formatShortFileSize(getContext(), highRam));
                 mForegroundProcessText.setText(getResources().getString(
                         R.string.running_processes_header_ram, sizeStr));
-                mColorBar.setRatios(highRam/(float)totalRam,
-                        medRam/(float)totalRam,
-                        lowRam/(float)totalRam);
+                int progress = (int) ((highRam/(float) totalRam) * 100);
+                mColorBar.setProgress(progress);
+                mColorBar.setSecondaryProgress(progress + (int) ((medRam/(float) totalRam) * 100));
             }
         }
     }
@@ -446,17 +448,22 @@
         mListView.setAdapter(mAdapter);
         mHeader = inflater.inflate(R.layout.running_processes_header, null);
         mListView.addHeaderView(mHeader, null, false /* set as not selectable */);
-        mColorBar = (LinearColorBar)mHeader.findViewById(R.id.color_bar);
+        mColorBar = mHeader.findViewById(R.id.color_bar);
         final Context context = getContext();
-        mColorBar.setColors(context.getColor(R.color.running_processes_system_ram),
-                Utils.getColorAccent(context),
-                context.getColor(R.color.running_processes_free_ram));
-        mBackgroundProcessPrefix = (TextView)mHeader.findViewById(R.id.freeSizePrefix);
-        mAppsProcessPrefix = (TextView)mHeader.findViewById(R.id.appsSizePrefix);
-        mForegroundProcessPrefix = (TextView)mHeader.findViewById(R.id.systemSizePrefix);
-        mBackgroundProcessText = (TextView)mHeader.findViewById(R.id.freeSize);
-        mAppsProcessText = (TextView)mHeader.findViewById(R.id.appsSize);
-        mForegroundProcessText = (TextView)mHeader.findViewById(R.id.systemSize);
+        mColorBar.setProgressTintList(
+                ColorStateList.valueOf(context.getColor(R.color.running_processes_system_ram)));
+        mColorBar.setSecondaryProgressTintList(
+                ColorStateList.valueOf(Utils.getColorAccent(context)));
+        mColorBar.setSecondaryProgressTintMode(PorterDuff.Mode.SRC);
+        mColorBar.setProgressBackgroundTintList(
+                ColorStateList.valueOf(context.getColor(R.color.running_processes_free_ram)));
+        mColorBar.setProgressBackgroundTintMode(PorterDuff.Mode.SRC);
+        mBackgroundProcessPrefix = mHeader.findViewById(R.id.freeSizePrefix);
+        mAppsProcessPrefix = mHeader.findViewById(R.id.appsSizePrefix);
+        mForegroundProcessPrefix = mHeader.findViewById(R.id.systemSizePrefix);
+        mBackgroundProcessText = mHeader.findViewById(R.id.freeSize);
+        mAppsProcessText = mHeader.findViewById(R.id.appsSize);
+        mForegroundProcessText = mHeader.findViewById(R.id.systemSize);
 
         ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
         mAm.getMemoryInfo(memInfo);
diff --git a/src/com/android/settings/widget/LinearColorBar.java b/src/com/android/settings/widget/LinearColorBar.java
deleted file mode 100644
index df1403e..0000000
--- a/src/com/android/settings/widget/LinearColorBar.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2018 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.settings.widget;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.widget.LinearLayout;
-
-import com.android.settings.Utils;
-
-/**
- * @Deprecated Use {@link android.widget.ProgressBar} instead.
- */
-public class LinearColorBar extends LinearLayout {
-
-    static final int RIGHT_COLOR = 0xffced7db;
-    static final int GRAY_COLOR = 0xff555555;
-    static final int WHITE_COLOR = 0xffffffff;
-
-    private float mRedRatio;
-    private float mYellowRatio;
-    private float mGreenRatio;
-
-    private int mLeftColor;
-    private int mMiddleColor;
-    private int mRightColor = RIGHT_COLOR;
-
-    private int mColoredRegions = REGION_RED | REGION_YELLOW | REGION_GREEN;
-
-    final Rect mRect = new Rect();
-    final Paint mPaint = new Paint();
-
-    int mLineWidth;
-
-    int mLastRegion;
-
-    final Paint mColorGradientPaint = new Paint();
-    final Paint mEdgeGradientPaint = new Paint();
-
-    public static final int REGION_RED = 1 << 0;
-    public static final int REGION_YELLOW = 1 << 1;
-    public static final int REGION_GREEN = 1 << 2;
-
-    public LinearColorBar(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        setWillNotDraw(false);
-        mPaint.setStyle(Paint.Style.FILL);
-        mColorGradientPaint.setStyle(Paint.Style.FILL);
-        mColorGradientPaint.setAntiAlias(true);
-        mEdgeGradientPaint.setStyle(Paint.Style.STROKE);
-        mLineWidth = getResources().getDisplayMetrics().densityDpi >= DisplayMetrics.DENSITY_HIGH
-                ? 2 : 1;
-        mEdgeGradientPaint.setStrokeWidth(mLineWidth);
-        mEdgeGradientPaint.setAntiAlias(true);
-        mLeftColor = mMiddleColor = Utils.getColorAccent(context);
-    }
-
-    public void setRatios(float red, float yellow, float green) {
-        mRedRatio = red;
-        mYellowRatio = yellow;
-        mGreenRatio = green;
-        invalidate();
-    }
-
-    public void setColors(int red, int yellow, int green) {
-        mLeftColor = red;
-        mMiddleColor = yellow;
-        mRightColor = green;
-        updateIndicator();
-        invalidate();
-    }
-
-    private void updateIndicator() {
-        int off = getPaddingTop() - getPaddingBottom();
-        if (off < 0) off = 0;
-        mRect.top = off;
-        mRect.bottom = getHeight();
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-        updateIndicator();
-    }
-
-    @Override
-    protected void dispatchSetPressed(boolean pressed) {
-        invalidate();
-    }
-
-    private int pickColor(int color, int region) {
-        if (isPressed() && (mLastRegion & region) != 0) {
-            return WHITE_COLOR;
-        }
-        if ((mColoredRegions & region) == 0) {
-            return GRAY_COLOR;
-        }
-        return color;
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        final int width = getWidth();
-
-        if (!isLayoutRtl()) {
-            drawLtr(canvas, width);
-        } else {
-            drawRtl(canvas, width);
-        }
-    }
-
-    private void drawLtr(Canvas canvas, int width) {
-        int start = 0;
-        int end = start + (int) (width * mRedRatio);
-        int end2 = end + (int) (width * mYellowRatio);
-
-        if (start < end) {
-            mRect.left = start;
-            mRect.right = end;
-            mPaint.setColor(pickColor(mLeftColor, REGION_RED));
-            canvas.drawRect(mRect, mPaint);
-            start = end;
-        }
-
-        end = end2;
-
-        if (start < end) {
-            mRect.left = start;
-            mRect.right = end;
-            mPaint.setColor(pickColor(mMiddleColor, REGION_YELLOW));
-            canvas.drawRect(mRect, mPaint);
-            start = end;
-        }
-
-        end = width;
-        if (start < end) {
-            mRect.left = start;
-            mRect.right = end;
-            mPaint.setColor(pickColor(mRightColor, REGION_GREEN));
-            canvas.drawRect(mRect, mPaint);
-        }
-    }
-
-    private void drawRtl(Canvas canvas, int width) {
-        int start = width;
-        int end = start - (int) (width * mRedRatio);
-        int end2 = end - (int) (width * mYellowRatio);
-
-        if (start > end) {
-            mRect.left = end;
-            mRect.right = start;
-            mPaint.setColor(pickColor(mLeftColor, REGION_RED));
-            canvas.drawRect(mRect, mPaint);
-            start = end;
-        }
-
-        end = end2;
-
-        if (start > end) {
-            mRect.left = end;
-            mRect.right = start;
-            mPaint.setColor(pickColor(mMiddleColor, REGION_YELLOW));
-            canvas.drawRect(mRect, mPaint);
-            start = end;
-        }
-
-        end = 0;
-        if (start > end) {
-            mRect.left = end;
-            mRect.right = start;
-            mPaint.setColor(pickColor(mRightColor, REGION_GREEN));
-            canvas.drawRect(mRect, mPaint);
-        }
-    }
-}
\ No newline at end of file
