Merge "Update SignalDrawable." into qt-dev
diff --git a/core/res/res/drawable/ic_signal_cellular.xml b/core/res/res/drawable/ic_signal_cellular.xml
new file mode 100644
index 0000000..fdde0d1
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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
+  -->
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:minLevel="0" android:maxLevel="0" android:drawable="@drawable/ic_signal_cellular_0_4_bar" />
+    <item android:minLevel="1" android:maxLevel="1" android:drawable="@drawable/ic_signal_cellular_1_4_bar" />
+    <item android:minLevel="2" android:maxLevel="2" android:drawable="@drawable/ic_signal_cellular_2_4_bar" />
+    <item android:minLevel="3" android:maxLevel="3" android:drawable="@drawable/ic_signal_cellular_3_4_bar" />
+    <item android:minLevel="4" android:maxLevel="4" android:drawable="@drawable/ic_signal_cellular_4_4_bar" />
+    <item android:minLevel="10" android:maxLevel="10" android:drawable="@drawable/ic_signal_cellular_0_5_bar" />
+    <item android:minLevel="11" android:maxLevel="11" android:drawable="@drawable/ic_signal_cellular_1_5_bar" />
+    <item android:minLevel="12" android:maxLevel="12" android:drawable="@drawable/ic_signal_cellular_2_5_bar" />
+    <item android:minLevel="13" android:maxLevel="13" android:drawable="@drawable/ic_signal_cellular_3_5_bar" />
+    <item android:minLevel="14" android:maxLevel="14" android:drawable="@drawable/ic_signal_cellular_4_5_bar" />
+    <item android:minLevel="15" android:maxLevel="15" android:drawable="@drawable/ic_signal_cellular_5_5_bar" />
+</level-list>
diff --git a/core/res/res/drawable/ic_signal_cellular_0_4_bar.xml b/core/res/res/drawable/ic_signal_cellular_0_4_bar.xml
new file mode 100644
index 0000000..9f6fa2f
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular_0_4_bar.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,7v13H7L20,7 M22,2L2,22h20V2L22,2z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_signal_cellular_0_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_0_5_bar.xml
new file mode 100644
index 0000000..9f6fa2f
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular_0_5_bar.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,7v13H7L20,7 M22,2L2,22h20V2L22,2z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_signal_cellular_1_4_bar.xml b/core/res/res/drawable/ic_signal_cellular_1_4_bar.xml
new file mode 100644
index 0000000..c0fe536
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular_1_4_bar.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,7v13H7L20,7 M22,2L2,22h20V2L22,2z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M 11 13 L 2 22 L 11 22 Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_signal_cellular_1_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_1_5_bar.xml
new file mode 100644
index 0000000..816da22
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular_1_5_bar.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,7V20H7L20,7m2-5L2,22H22V2Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M8.72,15.28,2,22H8.72V15.28Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_signal_cellular_2_4_bar.xml b/core/res/res/drawable/ic_signal_cellular_2_4_bar.xml
new file mode 100644
index 0000000..69a966b
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular_2_4_bar.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,7v13H7L20,7 M22,2L2,22h20V2L22,2z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M 13 11 L 2 22 L 13 22 Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_signal_cellular_2_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_2_5_bar.xml
new file mode 100644
index 0000000..02c7a43
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular_2_5_bar.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,7V20H7L20,7m2-5L2,22H22V2Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M 11.45 12.55 L 2 22 L 11.45 22 L 11.45 12.55 Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_signal_cellular_3_4_bar.xml b/core/res/res/drawable/ic_signal_cellular_3_4_bar.xml
new file mode 100644
index 0000000..46ce47c
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular_3_4_bar.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,7v13H7L20,7 M22,2L2,22h20V2L22,2z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M 2 22 L 16 22 L 16 21 L 16 20 L 16 11 L 16 10 L 16 8 Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_signal_cellular_3_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_3_5_bar.xml
new file mode 100644
index 0000000..37435e6
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular_3_5_bar.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,7V20H7L20,7m2-5L2,22H22V2Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M 14.96 9.04 L 2 22 L 14.96 22 L 14.96 9.04 Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_signal_cellular_4_4_bar.xml b/core/res/res/drawable/ic_signal_cellular_4_4_bar.xml
new file mode 100644
index 0000000..f93e40d
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular_4_4_bar.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M22,2L2,22h20V2L22,2z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_signal_cellular_4_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_4_5_bar.xml
new file mode 100644
index 0000000..6dc3646
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular_4_5_bar.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,7V20H7L20,7m2-5L2,22H22V2Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M 18.48 5.52 L 2 22 L 18.48 22 L 18.48 5.52 Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_signal_cellular_5_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_5_5_bar.xml
new file mode 100644
index 0000000..f93e40d
--- /dev/null
+++ b/core/res/res/drawable/ic_signal_cellular_5_5_bar.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M22,2L2,22h20V2L22,2z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e7e4d08..18a019a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1410,6 +1410,7 @@
   <java-symbol type="drawable" name="ic_signal_wifi_transient_animation" />
   <java-symbol type="drawable" name="ic_hotspot_transient_animation" />
   <java-symbol type="drawable" name="ic_bluetooth_transient_animation" />
+  <java-symbol type="drawable" name="ic_signal_cellular" />
   <java-symbol type="drawable" name="stat_notify_rssi_in_range" />
   <java-symbol type="drawable" name="stat_sys_gps_on" />
   <java-symbol type="drawable" name="stat_sys_tether_wifi" />
diff --git a/packages/SettingsLib/res/values/colors.xml b/packages/SettingsLib/res/values/colors.xml
index 209b2cb..5e8779f 100644
--- a/packages/SettingsLib/res/values/colors.xml
+++ b/packages/SettingsLib/res/values/colors.xml
@@ -35,4 +35,8 @@
     <color name="bt_color_bg_5">#fdcfe8</color> <!-- Material Pink 100 -->
     <color name="bt_color_bg_6">#e9d2fd</color> <!-- Material Purple 100 -->
     <color name="bt_color_bg_7">#cbf0f8</color> <!-- Material Cyan 100 -->
+
+
+    <color name="dark_mode_icon_color_single_tone">#99000000</color>
+    <color name="light_mode_icon_color_single_tone">#ffffff</color>
 </resources>
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index 2cb9d4b..d10e034 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -88,8 +88,6 @@
 
     <!-- SignalDrawable -->
     <dimen name="signal_icon_size">15dp</dimen>
-    <!-- How far to inset the rounded edges -->
-    <dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen>
 
     <!-- Size of nearby icon -->
     <dimen name="bt_nearby_icon_size">24dp</dimen>
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
index 4bd1bbb..cb0b7c2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
@@ -19,25 +19,28 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
-import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Path.Direction;
 import android.graphics.Path.FillType;
-import android.graphics.Path.Op;
-import android.graphics.PointF;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
+import android.graphics.drawable.DrawableWrapper;
 import android.os.Handler;
+import android.telephony.SignalStrength;
 import android.util.LayoutDirection;
 
 import com.android.settingslib.R;
 import com.android.settingslib.Utils;
 
-public class SignalDrawable extends Drawable {
+/**
+ * Drawable displaying a mobile cell signal indicator.
+ */
+public class SignalDrawable extends DrawableWrapper {
 
     private static final String TAG = "SignalDrawable";
 
@@ -48,11 +51,7 @@
     private static final float CUT_OUT = 7.9f / VIEWPORT;
 
     private static final float DOT_SIZE = 3f / VIEWPORT;
-    private static final float DOT_PADDING = 1f / VIEWPORT;
-    private static final float DOT_CUT_WIDTH = (DOT_SIZE * 3) + (DOT_PADDING * 5);
-    private static final float DOT_CUT_HEIGHT = (DOT_SIZE * 1) + (DOT_PADDING * 1);
-
-    private static final float[] FIT = {2.26f, -3.02f, 1.76f};
+    private static final float DOT_PADDING = 1.5f / VIEWPORT;
 
     // All of these are masks to push all of the drawable state into one int for easy callbacks
     // and flow through sysui.
@@ -61,11 +60,8 @@
     private static final int NUM_LEVEL_MASK = 0xff << NUM_LEVEL_SHIFT;
     private static final int STATE_SHIFT = 16;
     private static final int STATE_MASK = 0xff << STATE_SHIFT;
-    private static final int STATE_NONE = 0;
-    private static final int STATE_EMPTY = 1;
     private static final int STATE_CUT = 2;
     private static final int STATE_CARRIER_CHANGE = 3;
-    private static final int STATE_AIRPLANE = 4;
 
     private static final long DOT_DELAY = 1000;
 
@@ -84,76 +80,30 @@
             {-1.9f / VIEWPORT, -1.9f / VIEWPORT},
     };
 
-    // Rounded corners are achieved by arcing a circle of radius `R` from its tangent points along
-    // the curve (curve ≡ triangle). On the top and left corners of the triangle, the tangents are
-    // as follows:
-    //      1) Along the straight lines (y = 0 and x = width):
-    //          Ps = circleOffset + R
-    //      2) Along the diagonal line (y = x):
-    //          Pd = √((Ps^2) / 2)
-    //              or (remember: sin(π/4) ≈ 0.7071)
-    //          Pd = (circleOffset + R - 0.7071, height - R - 0.7071)
-    //         Where Pd is the (x,y) coords of the point that intersects the circle at the bottom
-    //         left of the triangle
-    private static final float RADIUS_RATIO = 0.75f / 17f;
-    private static final float DIAG_OFFSET_MULTIPLIER = 0.707107f;
-    // How far the circle defining the corners is inset from the edges
-    private final float mAppliedCornerInset;
-
-    private static final float INV_TAN = 1f / (float) Math.tan(Math.PI / 8f);
-    private static final float CUT_WIDTH_DP = 1f / 12f;
-
-    // Where the top and left points of the triangle would be if not for rounding
-    private final PointF mVirtualTop  = new PointF();
-    private final PointF mVirtualLeft = new PointF();
-
-    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private final Paint mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-    private final int mDarkModeBackgroundColor;
+    private final Paint mTransparentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private final int mDarkModeFillColor;
-    private final int mLightModeBackgroundColor;
     private final int mLightModeFillColor;
-    private final Path mFullPath = new Path();
+    private final Path mCutoutPath = new Path();
     private final Path mForegroundPath = new Path();
     private final Path mXPath = new Path();
-    // Cut out when STATE_EMPTY
-    private final Path mCutPath = new Path();
-    // Draws the slash when in airplane mode
-    private final SlashArtist mSlash = new SlashArtist();
     private final Handler mHandler;
-    private float mOldDarkIntensity = -1;
-    private float mNumLevels = 1;
-    private int mIntrinsicSize;
-    private int mLevel;
-    private int mState;
-    private boolean mVisible;
+    private float mDarkIntensity = -1;
+    private final int mIntrinsicSize;
     private boolean mAnimating;
     private int mCurrentDot;
 
     public SignalDrawable(Context context) {
-        mDarkModeBackgroundColor =
-                Utils.getColorStateListDefaultColor(context,
-                        R.color.dark_mode_icon_color_dual_tone_background);
-        mDarkModeFillColor =
-                Utils.getColorStateListDefaultColor(context,
-                        R.color.dark_mode_icon_color_dual_tone_fill);
-        mLightModeBackgroundColor =
-                Utils.getColorStateListDefaultColor(context,
-                        R.color.light_mode_icon_color_dual_tone_background);
-        mLightModeFillColor =
-                Utils.getColorStateListDefaultColor(context,
-                        R.color.light_mode_icon_color_dual_tone_fill);
+        super(context.getDrawable(com.android.internal.R.drawable.ic_signal_cellular));
+        mDarkModeFillColor = Utils.getColorStateListDefaultColor(context,
+                R.color.dark_mode_icon_color_single_tone);
+        mLightModeFillColor = Utils.getColorStateListDefaultColor(context,
+                R.color.light_mode_icon_color_single_tone);
         mIntrinsicSize = context.getResources().getDimensionPixelSize(R.dimen.signal_icon_size);
-
+        mTransparentPaint.setColor(context.getColor(android.R.color.transparent));
+        mTransparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
         mHandler = new Handler();
         setDarkIntensity(0);
-
-        mAppliedCornerInset = context.getResources()
-                .getDimensionPixelSize(R.dimen.stat_sys_mobile_signal_circle_inset);
-    }
-
-    public void setIntrinsicSize(int size) {
-        mIntrinsicSize = size;
     }
 
     @Override
@@ -166,21 +116,8 @@
         return mIntrinsicSize;
     }
 
-    public void setNumLevels(int levels) {
-        if (levels == mNumLevels) return;
-        mNumLevels = levels;
-        invalidateSelf();
-    }
-
-    private void setSignalState(int state) {
-        if (state == mState) return;
-        mState = state;
-        updateAnimation();
-        invalidateSelf();
-    }
-
     private void updateAnimation() {
-        boolean shouldAnimate = (mState == STATE_CARRIER_CHANGE) && mVisible;
+        boolean shouldAnimate = isInState(STATE_CARRIER_CHANGE) && isVisible();
         if (shouldAnimate == mAnimating) return;
         mAnimating = shouldAnimate;
         if (shouldAnimate) {
@@ -191,33 +128,33 @@
     }
 
     @Override
-    protected boolean onLevelChange(int state) {
-        setNumLevels(getNumLevels(state));
-        setSignalState(getState(state));
-        int level = getLevel(state);
-        if (level != mLevel) {
-            mLevel = level;
-            invalidateSelf();
-        }
+    protected boolean onLevelChange(int packedState) {
+        super.onLevelChange(unpackLevel(packedState));
+        updateAnimation();
+        setTintList(ColorStateList.valueOf(mForegroundPaint.getColor()));
         return true;
     }
 
-    public void setColors(int background, int foreground) {
-        int colorBackground = mPaint.getColor();
-        int colorForeground = mForegroundPaint.getColor();
-        mPaint.setColor(background);
-        mForegroundPaint.setColor(foreground);
-        if (colorBackground != background || colorForeground != foreground) invalidateSelf();
+    private int unpackLevel(int packedState) {
+        int numBins = (packedState & NUM_LEVEL_MASK) >> NUM_LEVEL_SHIFT;
+        int levelOffset = numBins == (SignalStrength.NUM_SIGNAL_STRENGTH_BINS + 1) ? 10 : 0;
+        int level = (packedState & LEVEL_MASK);
+        return level + levelOffset;
     }
 
     public void setDarkIntensity(float darkIntensity) {
-        if (darkIntensity == mOldDarkIntensity) {
+        if (darkIntensity == mDarkIntensity) {
             return;
         }
-        mPaint.setColor(getBackgroundColor(darkIntensity));
-        mForegroundPaint.setColor(getFillColor(darkIntensity));
-        mOldDarkIntensity = darkIntensity;
-        invalidateSelf();
+        setTintList(ColorStateList.valueOf(getFillColor(darkIntensity)));
+    }
+
+    @Override
+    public void setTintList(ColorStateList tint) {
+        super.setTintList(tint);
+        int colorForeground = mForegroundPaint.getColor();
+        mForegroundPaint.setColor(tint.getDefaultColor());
+        if (colorForeground != mForegroundPaint.getColor()) invalidateSelf();
     }
 
     private int getFillColor(float darkIntensity) {
@@ -225,11 +162,6 @@
                 darkIntensity, mLightModeFillColor, mDarkModeFillColor);
     }
 
-    private int getBackgroundColor(float darkIntensity) {
-        return getColorForDarkIntensity(
-                darkIntensity, mLightModeBackgroundColor, mDarkModeBackgroundColor);
-    }
-
     private int getColorForDarkIntensity(float darkIntensity, int lightColor, int darkColor) {
         return (int) ArgbEvaluator.getInstance().evaluate(darkIntensity, lightColor, darkColor);
     }
@@ -242,6 +174,7 @@
 
     @Override
     public void draw(@NonNull Canvas canvas) {
+        canvas.saveLayer(null, null);
         final float width = getBounds().width();
         final float height = getBounds().height();
 
@@ -252,113 +185,32 @@
             canvas.translate(width, 0);
             canvas.scale(-1.0f, 1.0f);
         }
-        mFullPath.reset();
-        mFullPath.setFillType(FillType.WINDING);
+        super.draw(canvas);
+        mCutoutPath.reset();
+        mCutoutPath.setFillType(FillType.WINDING);
 
         final float padding = Math.round(PAD * width);
-        final float cornerRadius = RADIUS_RATIO * height;
-        // Offset from circle where the hypotenuse meets the circle
-        final float diagOffset = DIAG_OFFSET_MULTIPLIER * cornerRadius;
 
-        // 1 - Bottom right, above corner
-        mFullPath.moveTo(width - padding, height - padding - cornerRadius);
-        // 2 - Line to top right, below corner
-        mFullPath.lineTo(width - padding, padding + cornerRadius + mAppliedCornerInset);
-        // 3 - Arc to top right, on hypotenuse
-        mFullPath.arcTo(
-                width - padding - (2 * cornerRadius),
-                padding + mAppliedCornerInset,
-                width - padding,
-                padding + mAppliedCornerInset + (2 * cornerRadius),
-                0.f, -135.f, false
-        );
-        // 4 - Line to bottom left, on hypotenuse
-        mFullPath.lineTo(padding + mAppliedCornerInset + cornerRadius - diagOffset,
-                height - padding - cornerRadius - diagOffset);
-        // 5 - Arc to bottom left, on leg
-        mFullPath.arcTo(
-                padding + mAppliedCornerInset,
-                height - padding - (2 * cornerRadius),
-                padding + mAppliedCornerInset + ( 2 * cornerRadius),
-                height - padding,
-                -135.f, -135.f, false
-        );
-        // 6 - Line to bottom rght, before corner
-        mFullPath.lineTo(width - padding - cornerRadius, height - padding);
-        // 7 - Arc to beginning (bottom right, above corner)
-        mFullPath.arcTo(
-                width - padding - (2 * cornerRadius),
-                height - padding - (2 * cornerRadius),
-                width - padding,
-                height - padding,
-                90.f, -90.f, false
-        );
-
-        if (mState == STATE_CARRIER_CHANGE) {
-            float cutWidth = (DOT_CUT_WIDTH * width);
-            float cutHeight = (DOT_CUT_HEIGHT * width);
+        if (isInState(STATE_CARRIER_CHANGE)) {
             float dotSize = (DOT_SIZE * height);
             float dotPadding = (DOT_PADDING * height);
-
-            mFullPath.moveTo(width - padding, height - padding);
-            mFullPath.rLineTo(-cutWidth, 0);
-            mFullPath.rLineTo(0, -cutHeight);
-            mFullPath.rLineTo(cutWidth, 0);
-            mFullPath.rLineTo(0, cutHeight);
-            float dotSpacing = dotPadding * 2 + dotSize;
+            float dotSpacing = dotPadding + dotSize;
             float x = width - padding - dotSize;
             float y = height - padding - dotSize;
             mForegroundPath.reset();
-            drawDot(mFullPath, mForegroundPath, x, y, dotSize, 2);
-            drawDot(mFullPath, mForegroundPath, x - dotSpacing, y, dotSize, 1);
-            drawDot(mFullPath, mForegroundPath, x - dotSpacing * 2, y, dotSize, 0);
-        } else if (mState == STATE_CUT) {
+            drawDotAndPadding(x, y, dotPadding, dotSize, 2);
+            drawDotAndPadding(x - dotSpacing, y, dotPadding, dotSize, 1);
+            drawDotAndPadding(x - dotSpacing * 2, y, dotPadding, dotSize, 0);
+            canvas.drawPath(mCutoutPath, mTransparentPaint);
+            canvas.drawPath(mForegroundPath, mForegroundPaint);
+        } else if (isInState(STATE_CUT)) {
             float cut = (CUT_OUT * width);
-            mFullPath.moveTo(width - padding, height - padding);
-            mFullPath.rLineTo(-cut, 0);
-            mFullPath.rLineTo(0, -cut);
-            mFullPath.rLineTo(cut, 0);
-            mFullPath.rLineTo(0, cut);
-        }
-
-        if (mState == STATE_EMPTY) {
-            // Where the corners would be if this were a real triangle
-            mVirtualTop.set(
-                    width - padding,
-                    (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius));
-            mVirtualLeft.set(
-                    (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius),
-                    height - padding);
-
-            final float cutWidth = CUT_WIDTH_DP * height;
-            final float cutDiagInset = cutWidth * INV_TAN;
-
-            // Cut out a smaller triangle from the center of mFullPath
-            mCutPath.reset();
-            mCutPath.setFillType(FillType.WINDING);
-            mCutPath.moveTo(width - padding - cutWidth, height - padding - cutWidth);
-            mCutPath.lineTo(width - padding - cutWidth, mVirtualTop.y + cutDiagInset);
-            mCutPath.lineTo(mVirtualLeft.x + cutDiagInset, height - padding - cutWidth);
-            mCutPath.lineTo(width - padding - cutWidth, height - padding - cutWidth);
-
-            // Draw empty state as only background
-            mForegroundPath.reset();
-            mFullPath.op(mCutPath, Path.Op.DIFFERENCE);
-        } else if (mState == STATE_AIRPLANE) {
-            // Airplane mode is slashed, fully drawn background
-            mForegroundPath.reset();
-            mSlash.draw((int) height, (int) width, canvas, mPaint);
-        } else if (mState != STATE_CARRIER_CHANGE) {
-            mForegroundPath.reset();
-            int sigWidth = Math.round(calcFit(mLevel / (mNumLevels - 1)) * (width - 2 * padding));
-            mForegroundPath.addRect(padding, padding, padding + sigWidth, height - padding,
-                    Direction.CW);
-            mForegroundPath.op(mFullPath, Op.INTERSECT);
-        }
-
-        canvas.drawPath(mFullPath, mPaint);
-        canvas.drawPath(mForegroundPath, mForegroundPaint);
-        if (mState == STATE_CUT) {
+            mCutoutPath.moveTo(width - padding, height - padding);
+            mCutoutPath.rLineTo(-cut, 0);
+            mCutoutPath.rLineTo(0, -cut);
+            mCutoutPath.rLineTo(cut, 0);
+            mCutoutPath.rLineTo(0, cut);
+            canvas.drawPath(mCutoutPath, mTransparentPaint);
             mXPath.reset();
             mXPath.moveTo(X_PATH[0][0] * width, X_PATH[0][1] * height);
             for (int i = 1; i < X_PATH.length; i++) {
@@ -369,57 +221,37 @@
         if (isRtl) {
             canvas.restore();
         }
+        canvas.restore();
     }
 
-    private void drawDot(Path fullPath, Path foregroundPath, float x, float y, float dotSize,
-            int i) {
-        Path p = (i == mCurrentDot) ? foregroundPath : fullPath;
-        p.addRect(x, y, x + dotSize, y + dotSize, Direction.CW);
-    }
-
-    // This is a fit line based on previous values of provided in assets, but if
-    // you look at the a plot of this actual fit, it makes a lot of sense, what it does
-    // is compress the areas that are very visually easy to see changes (the middle sections)
-    // and spread out the sections that are hard to see (each end of the icon).
-    // The current fit is cubic, but pretty easy to change the way the code is written (just add
-    // terms to the end of FIT).
-    private float calcFit(float v) {
-        float ret = 0;
-        float t = v;
-        for (int i = 0; i < FIT.length; i++) {
-            ret += FIT[i] * t;
-            t *= v;
+    private void drawDotAndPadding(float x, float y,
+            float dotPadding, float dotSize, int i) {
+        if (i == mCurrentDot) {
+            // Draw dot
+            mForegroundPath.addRect(x, y, x + dotSize, y + dotSize, Direction.CW);
+            // Draw dot padding
+            mCutoutPath.addRect(x - dotPadding, y - dotPadding, x + dotSize + dotPadding,
+                    y + dotSize + dotPadding, Direction.CW);
         }
-        return ret;
-    }
-
-    @Override
-    public int getAlpha() {
-        return mPaint.getAlpha();
     }
 
     @Override
     public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {
-        mPaint.setAlpha(alpha);
+        super.setAlpha(alpha);
         mForegroundPaint.setAlpha(alpha);
     }
 
     @Override
     public void setColorFilter(@Nullable ColorFilter colorFilter) {
-        mPaint.setColorFilter(colorFilter);
+        super.setColorFilter(colorFilter);
         mForegroundPaint.setColorFilter(colorFilter);
     }
 
     @Override
-    public int getOpacity() {
-        return 255;
-    }
-
-    @Override
     public boolean setVisible(boolean visible, boolean restart) {
-        mVisible = visible;
+        boolean changed = super.setVisible(visible, restart);
         updateAnimation();
-        return super.setVisible(visible, restart);
+        return changed;
     }
 
     private final Runnable mChangeDot = new Runnable() {
@@ -433,92 +265,33 @@
         }
     };
 
-    public static int getLevel(int fullState) {
-        return fullState & LEVEL_MASK;
+    /**
+     * Returns whether this drawable is in the specified state.
+     *
+     * @param state must be one of {@link #STATE_CARRIER_CHANGE} or {@link #STATE_CUT}
+     */
+    private boolean isInState(int state) {
+        return getState(getLevel()) == state;
     }
 
     public static int getState(int fullState) {
         return (fullState & STATE_MASK) >> STATE_SHIFT;
     }
 
-    public static int getNumLevels(int fullState) {
-        return (fullState & NUM_LEVEL_MASK) >> NUM_LEVEL_SHIFT;
-    }
-
     public static int getState(int level, int numLevels, boolean cutOut) {
         return ((cutOut ? STATE_CUT : 0) << STATE_SHIFT)
                 | (numLevels << NUM_LEVEL_SHIFT)
                 | level;
     }
 
+    /** Returns the state representing empty mobile signal with the given number of levels. */
+    public static int getEmptyState(int numLevels) {
+        // TODO empty state == 0 state. does there need to be a new drawable for this?
+        return getState(0, numLevels, false);
+    }
+
+    /** Returns the state representing carrier change with the given number of levels. */
     public static int getCarrierChangeState(int numLevels) {
         return (STATE_CARRIER_CHANGE << STATE_SHIFT) | (numLevels << NUM_LEVEL_SHIFT);
     }
-
-    public static int getEmptyState(int numLevels) {
-        return (STATE_EMPTY << STATE_SHIFT) | (numLevels << NUM_LEVEL_SHIFT);
-    }
-
-    public static int getAirplaneModeState(int numLevels) {
-        return (STATE_AIRPLANE << STATE_SHIFT) | (numLevels << NUM_LEVEL_SHIFT);
-    }
-
-    private final class SlashArtist {
-        private static final float CORNER_RADIUS = 1f;
-        // These values are derived in un-rotated (vertical) orientation
-        private static final float SLASH_WIDTH = 1.8384776f;
-        private static final float SLASH_HEIGHT = 22f;
-        private static final float CENTER_X = 10.65f;
-        private static final float CENTER_Y = 15.869239f;
-        private static final float SCALE = 24f;
-
-        // Bottom is derived during animation
-        private static final float LEFT = (CENTER_X - (SLASH_WIDTH / 2)) / SCALE;
-        private static final float TOP = (CENTER_Y - (SLASH_HEIGHT / 2)) / SCALE;
-        private static final float RIGHT = (CENTER_X + (SLASH_WIDTH / 2)) / SCALE;
-        private static final float BOTTOM = (CENTER_Y + (SLASH_HEIGHT / 2)) / SCALE;
-        // Draw the slash washington-monument style; rotate to no-u-turn style
-        private static final float ROTATION = -45f;
-
-        private final Path mPath = new Path();
-        private final RectF mSlashRect = new RectF();
-
-        void draw(int height, int width, @NonNull Canvas canvas, Paint paint) {
-            Matrix m = new Matrix();
-            final float radius = scale(CORNER_RADIUS, width);
-            updateRect(
-                    scale(LEFT, width),
-                    scale(TOP, height),
-                    scale(RIGHT, width),
-                    scale(BOTTOM, height));
-
-            mPath.reset();
-            // Draw the slash vertically
-            mPath.addRoundRect(mSlashRect, radius, radius, Direction.CW);
-            m.setRotate(ROTATION, width / 2, height / 2);
-            mPath.transform(m);
-            canvas.drawPath(mPath, paint);
-
-            // Rotate back to vertical, and draw the cut-out rect next to this one
-            m.setRotate(-ROTATION, width / 2, height / 2);
-            mPath.transform(m);
-            m.setTranslate(mSlashRect.width(), 0);
-            mPath.transform(m);
-            mPath.addRoundRect(mSlashRect, radius, radius, Direction.CW);
-            m.setRotate(ROTATION, width / 2, height / 2);
-            mPath.transform(m);
-            canvas.clipOutPath(mPath);
-        }
-
-        void updateRect(float left, float top, float right, float bottom) {
-            mSlashRect.left = left;
-            mSlashRect.top = top;
-            mSlashRect.right = right;
-            mSlashRect.bottom = bottom;
-        }
-
-        private float scale(float frac, int width) {
-            return frac * width;
-        }
-    }
 }
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 88466ce..32879c0 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -111,11 +111,9 @@
 
     <color name="segmented_buttons_background">#14FFFFFF</color><!-- 8% white -->
 
-    <color name="dark_mode_icon_color_single_tone">#99000000</color>
     <color name="dark_mode_icon_color_dual_tone_background">#3d000000</color>
     <color name="dark_mode_icon_color_dual_tone_fill">#7a000000</color>
 
-    <color name="light_mode_icon_color_single_tone">#ffffff</color>
     <color name="light_mode_icon_color_dual_tone_background">#4dffffff</color>
     <color name="light_mode_icon_color_dual_tone_fill">#ffffff</color>
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java b/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
deleted file mode 100644
index c1aa706..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
+++ /dev/null
@@ -1,78 +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.qs;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.service.quicksettings.Tile;
-import android.widget.ImageView;
-
-import com.android.settingslib.graph.SignalDrawable;
-import com.android.systemui.R;
-import com.android.systemui.plugins.qs.QSTile.Icon;
-import com.android.systemui.plugins.qs.QSTile.State;
-import com.android.systemui.qs.tileimpl.QSTileImpl;
-
-import java.util.Objects;
-
-// Exists to provide easy way to add sim icon to cell tile
-// TODO Find a better way to handle this and remove it.
-public class CellTileView extends SignalTileView {
-
-    private final SignalDrawable mSignalDrawable;
-
-    public CellTileView(Context context) {
-        super(context);
-        mSignalDrawable = new SignalDrawable(mContext);
-        mSignalDrawable.setColors(QSTileImpl.getColorForState(context, Tile.STATE_UNAVAILABLE),
-                QSTileImpl.getColorForState(context, Tile.STATE_ACTIVE));
-        mSignalDrawable.setIntrinsicSize(context.getResources().getDimensionPixelSize(
-                R.dimen.qs_tile_icon_size));
-    }
-
-    protected void updateIcon(ImageView iv, State state, boolean allowAnimations) {
-        if (!(state.icon instanceof SignalIcon)) {
-            super.updateIcon(iv, state, allowAnimations);
-            return;
-        } else if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
-            mSignalDrawable.setLevel(((SignalIcon) state.icon).getState());
-            iv.setImageDrawable(mSignalDrawable);
-            iv.setTag(R.id.qs_icon_tag, state.icon);
-        }
-    }
-
-    public static class SignalIcon extends Icon {
-
-        private final int mState;
-
-        public SignalIcon(int state) {
-            mState = state;
-        }
-
-        public int getState() {
-            return mState;
-        }
-
-        @Override
-        public Drawable getDrawable(Context context) {
-            //TODO: Not the optimal solution to create this drawable
-            SignalDrawable d = new SignalDrawable(context);
-            d.setColors(QSTileImpl.getColorForState(context, Tile.STATE_UNAVAILABLE),
-                    QSTileImpl.getColorForState(context, Tile.STATE_ACTIVE));
-            d.setLevel(getState());
-            return d;
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java b/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
index fd7efc9..c5bf402 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
@@ -75,12 +75,11 @@
         mMobileGroup.setVisibility(state.visible ? View.VISIBLE : View.GONE);
         if (state.visible) {
             mMobileRoaming.setVisibility(state.roaming ? View.VISIBLE : View.GONE);
-            mMobileRoaming.setImageTintList(ColorStateList.valueOf(
-                    mDualToneHandler.getSingleColor(mColorForegroundIntensity)));
-            SignalDrawable d = new SignalDrawable(mContext);
-            d.setColors(mDualToneHandler.getBackgroundColor(mColorForegroundIntensity),
-                    mDualToneHandler.getFillColor(mColorForegroundIntensity));
-            mMobileSignal.setImageDrawable(d);
+            ColorStateList colorStateList = ColorStateList.valueOf(
+                    mDualToneHandler.getSingleColor(mColorForegroundIntensity));
+            mMobileRoaming.setImageTintList(colorStateList);
+            mMobileSignal.setImageDrawable(new SignalDrawable(mContext));
+            mMobileSignal.setImageTintList(colorStateList);
             mMobileSignal.setImageLevel(state.mobileSignalIconId);
 
             StringBuilder contentDescription = new StringBuilder();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 20e002e..20069ea 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -40,9 +40,7 @@
 import com.android.systemui.R;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
-import com.android.systemui.plugins.qs.QSIconView;
 import com.android.systemui.plugins.qs.QSTile.SignalState;
-import com.android.systemui.qs.CellTileView;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
@@ -89,11 +87,6 @@
     }
 
     @Override
-    public QSIconView createTileView(Context context) {
-        return new CellTileView(context);
-    }
-
-    @Override
     public Intent getLongClickIntent() {
         return getCellularSettingIntent();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
index 9c6b3be..812c9a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
@@ -211,8 +211,8 @@
         if (!isInArea(area, this)) {
             return;
         }
-        mMobileDrawable.setColors(mDualToneHandler.getBackgroundColor(darkIntensity),
-                mDualToneHandler.getFillColor(darkIntensity));
+        mMobileDrawable.setTintList(
+                ColorStateList.valueOf(mDualToneHandler.getFillColor(darkIntensity)));
         ColorStateList color = ColorStateList.valueOf(getTint(area, this, tint));
         mIn.setImageTintList(color);
         mOut.setImageTintList(color);
@@ -237,8 +237,8 @@
         float intensity = color == Color.WHITE ? 0 : 1;
         // We want the ability to change the theme from the one set by SignalDrawable in certain
         // surfaces. In this way, we can pass a theme to the view.
-        mMobileDrawable.setColors(mDualToneHandler.getBackgroundColor(intensity),
-                mDualToneHandler.getFillColor(intensity));
+        mMobileDrawable.setTintList(
+                ColorStateList.valueOf(mDualToneHandler.getFillColor(intensity)));
         mIn.setImageTintList(list);
         mOut.setImageTintList(list);
         mMobileType.setImageTintList(list);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index c398ad8..c08390f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -284,10 +284,6 @@
 
     @Override
     public int getQsCurrentIconId() {
-        if (mCurrentState.airplaneMode) {
-            return SignalDrawable.getAirplaneModeState(getNumLevels());
-        }
-
         return getCurrentIconId();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 950f07d..b8a14ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -1012,6 +1012,12 @@
                                     SignalStrength.NUM_SIGNAL_STRENGTH_BINS);
                     controller.getState().connected = controller.getState().level >= 0;
                 }
+                if (args.containsKey("inflate")) {
+                    for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+                        mMobileSignalControllers.valueAt(i).mInflateSignalStrengths =
+                                "true".equals(args.getString("inflate"));
+                    }
+                }
                 String activity = args.getString("activity");
                 if (activity != null) {
                     controller.getState().dataConnected = true;