diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000000000..9add90cf1f48f
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000000000..9add90cf1f48f
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000000000..6c4e133558252
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
new file mode 100644
index 0000000000000..a8f5ce015421d
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
new file mode 100644
index 0000000000000..b9bb42d4134a5
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000000000..b8823a9495e8f
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000000000..b8823a9495e8f
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000000000..14c27766325e6
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
new file mode 100644
index 0000000000000..ea8f9796e54f8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
new file mode 100644
index 0000000000000..4e3a3563e6ed1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000000000..d05c4e1bd4cf4
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000000000..d05c4e1bd4cf4
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000000000..8bcbf1e36a1b0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
new file mode 100644
index 0000000000000..79b1827d8c7d9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
new file mode 100644
index 0000000000000..a8f5ce015421d
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000000000..c3ae6c1a7e9d9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000000000..c3ae6c1a7e9d9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000000000..fde172a9032b5
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
new file mode 100644
index 0000000000000..accf16d73872c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
new file mode 100644
index 0000000000000..15c67053448c5
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
new file mode 100644
index 0000000000000..bc545bae6e5b3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
new file mode 100644
index 0000000000000..400a28ba4e7d2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
new file mode 100644
index 0000000000000..0bd75d1871ae1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
new file mode 100644
index 0000000000000..5263eb49df665
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
new file mode 100644
index 0000000000000..1805a8e33290f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
new file mode 100644
index 0000000000000..565ef269743dc
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
new file mode 100644
index 0000000000000..feb30253cf238
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
new file mode 100644
index 0000000000000..f75617f04befb
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_qs_rotation_landscape.xml b/packages/SystemUI/res/drawable/ic_qs_rotation_landscape.xml
deleted file mode 100644
index 4bb3668f9108c..0000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_rotation_landscape.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
diff --git a/packages/SystemUI/res/drawable/ic_qs_rotation_portrait.xml b/packages/SystemUI/res/drawable/ic_qs_rotation_portrait.xml
deleted file mode 100644
index f0878c7113643..0000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_rotation_portrait.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
diff --git a/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml b/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml
deleted file mode 100644
index 94b3a6baf1cfa..0000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
new file mode 100644
index 0000000000000..76f5667f5fcc8
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
@@ -0,0 +1,18 @@
+
+
+
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
new file mode 100644
index 0000000000000..ac27e4dae3739
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
@@ -0,0 +1,18 @@
+
+
+
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 4e93cd8dfc529..4a9eb5586d984 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -35,5 +35,6 @@
+
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 6ef6e9e634ff7..2a66484fb556f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -18,11 +18,13 @@ package com.android.systemui.qs;
import android.content.Context;
import android.content.Intent;
+import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
+import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
@@ -299,10 +301,91 @@ public abstract class QSTile implements Listenable {
}
}
+ public static abstract class Icon {
+ abstract public Drawable getDrawable(Context context);
+
+ @Override
+ public int hashCode() {
+ return Icon.class.hashCode();
+ }
+ }
+
+ public static class ResourceIcon extends Icon {
+ private static final SparseArray ICONS = new SparseArray();
+
+ private final int mResId;
+
+ private ResourceIcon(int resId) {
+ mResId = resId;
+ }
+
+ public static Icon get(int resId) {
+ Icon icon = ICONS.get(resId);
+ if (icon == null) {
+ icon = new ResourceIcon(resId);
+ ICONS.put(resId, icon);
+ }
+ return icon;
+ }
+
+ @Override
+ public Drawable getDrawable(Context context) {
+ return context.getDrawable(mResId);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof ResourceIcon && ((ResourceIcon) o).mResId == mResId;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ResourceIcon[resId=0x%08x]", mResId);
+ }
+ }
+
+ protected class AnimationIcon extends ResourceIcon {
+ private boolean mAllowAnimation;
+
+ public AnimationIcon(int resId) {
+ super(resId);
+ }
+
+ public void setAllowAnimation(boolean allowAnimation) {
+ mAllowAnimation = allowAnimation;
+ }
+
+ @Override
+ public Drawable getDrawable(Context context) {
+ // workaround: get a clean state for every new AVD
+ final AnimatedVectorDrawable d = (AnimatedVectorDrawable) super.getDrawable(context)
+ .getConstantState().newDrawable();
+ d.start();
+ if (mAllowAnimation) {
+ mAllowAnimation = false;
+ } else {
+ d.stop(); // skip directly to end state
+ }
+ return d;
+ }
+ }
+
+ protected enum UserBoolean {
+ USER_TRUE(true, true),
+ USER_FALSE(true, false),
+ BACKGROUND_TRUE(false, true),
+ BACKGROUND_FALSE(false, false);
+ public final boolean value;
+ public final boolean userInitiated;
+ private UserBoolean(boolean userInitiated, boolean value) {
+ this.value = value;
+ this.userInitiated = userInitiated;
+ }
+ }
+
public static class State {
public boolean visible;
- public int iconId;
- public Drawable icon;
+ public Icon icon;
public String label;
public String contentDescription;
public String dualLabelContentDescription;
@@ -312,7 +395,6 @@ public abstract class QSTile implements Listenable {
if (other == null) throw new IllegalArgumentException();
if (!other.getClass().equals(getClass())) throw new IllegalArgumentException();
final boolean changed = other.visible != visible
- || other.iconId != iconId
|| !Objects.equals(other.icon, icon)
|| !Objects.equals(other.label, label)
|| !Objects.equals(other.contentDescription, contentDescription)
@@ -320,7 +402,6 @@ public abstract class QSTile implements Listenable {
|| !Objects.equals(other.dualLabelContentDescription,
dualLabelContentDescription);
other.visible = visible;
- other.iconId = iconId;
other.icon = icon;
other.label = label;
other.contentDescription = contentDescription;
@@ -335,9 +416,8 @@ public abstract class QSTile implements Listenable {
}
protected StringBuilder toStringBuilder() {
- final StringBuilder sb = new StringBuilder( getClass().getSimpleName()).append('[');
+ final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
sb.append("visible=").append(visible);
- sb.append(",iconId=").append(iconId);
sb.append(",icon=").append(icon);
sb.append(",label=").append(label);
sb.append(",contentDescription=").append(contentDescription);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index d5c90d0668bb2..6b7bdd61a761e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -21,6 +21,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Typeface;
+import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.os.Handler;
@@ -39,6 +40,8 @@ import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile.State;
+import java.util.Objects;
+
/** View that represents a standard quick settings tile. **/
public class QSTileView extends ViewGroup {
private static final Typeface CONDENSED = Typeface.create("sans-serif-condensed",
@@ -285,16 +288,7 @@ public class QSTileView extends ViewGroup {
protected void handleStateChanged(QSTile.State state) {
if (mIcon instanceof ImageView) {
- ImageView iv = (ImageView) mIcon;
- if (state.icon != null) {
- iv.setImageDrawable(state.icon);
- } else if (state.iconId > 0) {
- iv.setImageResource(state.iconId);
- }
- Drawable drawable = iv.getDrawable();
- if (state.autoMirrorDrawable && drawable != null) {
- drawable.setAutoMirrored(true);
- }
+ setIcon((ImageView) mIcon, state);
}
if (mDual) {
mDualLabel.setText(state.label);
@@ -306,6 +300,22 @@ public class QSTileView extends ViewGroup {
}
}
+ protected void setIcon(ImageView iv, QSTile.State state) {
+ if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
+ Drawable d = state.icon != null ? state.icon.getDrawable(mContext) : null;
+ if (d != null && state.autoMirrorDrawable) {
+ d.setAutoMirrored(true);
+ }
+ iv.setImageDrawable(d);
+ iv.setTag(R.id.qs_icon_tag, state.icon);
+ if (d instanceof Animatable) {
+ if (!iv.isShown()) {
+ ((Animatable) d).stop(); // skip directly to end state
+ }
+ }
+ }
+ }
+
public void onStateChanged(QSTile.State state) {
mHandler.obtainMessage(H.STATE_CHANGED, state).sendToTarget();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index cfcd74e8cf473..9ac79440ac45f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -104,7 +104,7 @@ public final class SignalTileView extends QSTileView {
protected void handleStateChanged(QSTile.State state) {
super.handleStateChanged(state);
final SignalState s = (SignalState) state;
- mSignal.setImageResource(s.iconId);
+ setIcon(mSignal, s);
if (s.overlayIconId > 0) {
mOverlay.setVisibility(VISIBLE);
mOverlay.setImageResource(s.overlayIconId);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 51401c8c96663..cd44a2bb20034 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -68,11 +68,11 @@ public class AirplaneModeTile extends QSTile {
state.visible = true;
state.label = mContext.getString(R.string.quick_settings_airplane_mode_label);
if (airplaneMode) {
- state.iconId = R.drawable.ic_qs_airplane_on;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_airplane_on);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_airplane_on);
} else {
- state.iconId = R.drawable.ic_qs_airplane_off;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_airplane_off);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_airplane_off);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 84bfb8fddca17..4d77348179410 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -92,17 +92,17 @@ public class BluetoothTile extends QSTile {
if (enabled) {
state.label = null;
if (connected) {
- state.iconId = R.drawable.ic_qs_bluetooth_connected;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_connected);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_bluetooth_connected);
state.label = mController.getLastDeviceName();
} else if (connecting) {
- state.iconId = R.drawable.ic_qs_bluetooth_connecting;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_connecting);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_bluetooth_connecting);
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
} else {
- state.iconId = R.drawable.ic_qs_bluetooth_on;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_bluetooth_on);
}
@@ -110,7 +110,7 @@ public class BluetoothTile extends QSTile {
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
}
} else {
- state.iconId = R.drawable.ic_qs_bluetooth_off;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_off);
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_bluetooth_off);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 8304291368081..5bf6fb5b5e5cc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -107,7 +107,8 @@ public class CastTile extends QSTile {
if (!state.value && connecting) {
state.label = mContext.getString(R.string.quick_settings_connecting);
}
- state.iconId = state.value ? R.drawable.ic_qs_cast_on : R.drawable.ic_qs_cast_off;
+ state.icon = ResourceIcon.get(state.value ? R.drawable.ic_qs_cast_on
+ : R.drawable.ic_qs_cast_off);
mDetailAdapter.updateItems(devices);
}
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 359a259ecf0f8..178590be3b23b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -87,16 +87,17 @@ public class CellularTile extends QSTile {
if (cb == null) return;
final Resources r = mContext.getResources();
- state.iconId = cb.noSim ? R.drawable.ic_qs_no_sim
+ final int iconId = cb.noSim ? R.drawable.ic_qs_no_sim
: !cb.enabled || cb.airplaneModeEnabled ? R.drawable.ic_qs_signal_disabled
: cb.mobileSignalIconId > 0 ? cb.mobileSignalIconId
: R.drawable.ic_qs_signal_no_signal;
+ state.icon = ResourceIcon.get(iconId);
state.isOverlayIconWide = cb.isDataTypeIconWide;
state.autoMirrorDrawable = !cb.noSim;
state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiConnected
? cb.dataTypeIconId
: 0;
- state.filter = state.iconId != R.drawable.ic_qs_no_sim;
+ state.filter = iconId != R.drawable.ic_qs_no_sim;
state.activityIn = cb.enabled && cb.activityIn;
state.activityOut = cb.enabled && cb.activityOut;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 7ba1dc03b2957..b24f8bf87afc3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -88,7 +88,8 @@ public class ColorInversionTile extends QSTile {
state.visible = enabled || mUsageTracker.isRecentlyUsed();
state.value = enabled;
state.label = mContext.getString(R.string.quick_settings_inversion_label);
- state.iconId = enabled ? R.drawable.ic_qs_inversion_on : R.drawable.ic_qs_inversion_off;
+ state.icon = ResourceIcon.get(enabled ? R.drawable.ic_qs_inversion_on
+ : R.drawable.ic_qs_inversion_off);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index e6b7f02586f11..055a6b79e714c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -92,8 +92,8 @@ public class FlashlightTile extends QSTile implements
// the camera is not available while it is being used for the flashlight.
state.visible = mWasLastOn != 0 || mFlashlightController.isAvailable();
state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
- state.iconId = state.value
- ? R.drawable.ic_qs_flashlight_on : R.drawable.ic_qs_flashlight_off;
+ state.icon = ResourceIcon.get(state.value ? R.drawable.ic_qs_flashlight_on
+ : R.drawable.ic_qs_flashlight_off);
int onOrOffId = state.value
? R.string.accessibility_quick_settings_flashlight_on
: R.string.accessibility_quick_settings_flashlight_off;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index b30a1d3c4d911..64dab858031d0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -71,8 +71,8 @@ public class HotspotTile extends QSTile {
state.label = mContext.getString(R.string.quick_settings_hotspot_label);
state.value = mController.isHotspotEnabled();
- state.iconId = state.visible && state.value ? R.drawable.ic_qs_hotspot_on
- : R.drawable.ic_qs_hotspot_off;
+ state.icon = ResourceIcon.get(state.visible && state.value ? R.drawable.ic_qs_hotspot_on
+ : R.drawable.ic_qs_hotspot_off);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index 58587e651bdc9..6fb9cd8972770 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -31,6 +31,9 @@ import android.util.Log;
import com.android.systemui.qs.QSTile;
+import java.util.Arrays;
+import java.util.Objects;
+
public class IntentTile extends QSTile {
public static final String PREFIX = "intent(";
@@ -96,13 +99,11 @@ public class IntentTile extends QSTile {
state.visible = intent.getBooleanExtra("visible", true);
state.contentDescription = intent.getStringExtra("contentDescription");
state.label = intent.getStringExtra("label");
- state.iconId = 0;
state.icon = null;
final byte[] iconBitmap = intent.getByteArrayExtra("iconBitmap");
if (iconBitmap != null) {
try {
- final Bitmap b = BitmapFactory.decodeByteArray(iconBitmap, 0, iconBitmap.length);
- state.icon = new BitmapDrawable(mContext.getResources(), b);
+ state.icon = new BytesIcon(iconBitmap);
} catch (Throwable t) {
Log.w(TAG, "Error loading icon bitmap, length " + iconBitmap.length, t);
}
@@ -111,9 +112,9 @@ public class IntentTile extends QSTile {
if (iconId != 0) {
final String iconPackage = intent.getStringExtra("iconPackage");
if (!TextUtils.isEmpty(iconPackage)) {
- state.icon = getPackageDrawable(iconPackage, iconId);
+ state.icon = new PackageDrawableIcon(iconPackage, iconId);
} else {
- state.iconId = iconId;
+ state.icon = ResourceIcon.get(iconId);
}
}
}
@@ -121,19 +122,66 @@ public class IntentTile extends QSTile {
mOnClickUri = intent.getStringExtra("onClickUri");
}
- private Drawable getPackageDrawable(String pkg, int id) {
- try {
- return mContext.createPackageContext(pkg, 0).getDrawable(id);
- } catch (Throwable t) {
- Log.w(TAG, "Error loading package drawable pkg=" + pkg + " id=" + id, t);
- return null;
- }
- }
-
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
refreshState(intent);
}
};
+
+ private static class BytesIcon extends Icon {
+ private final byte[] mBytes;
+
+ public BytesIcon(byte[] bytes) {
+ mBytes = bytes;
+ }
+
+ @Override
+ public Drawable getDrawable(Context context) {
+ final Bitmap b = BitmapFactory.decodeByteArray(mBytes, 0, mBytes.length);
+ return new BitmapDrawable(context.getResources(), b);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof BytesIcon && Arrays.equals(((BytesIcon) o).mBytes, mBytes);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("BytesIcon[len=%s]", mBytes.length);
+ }
+ }
+
+ private class PackageDrawableIcon extends Icon {
+ private final String mPackage;
+ private final int mResId;
+
+ public PackageDrawableIcon(String pkg, int resId) {
+ mPackage = pkg;
+ mResId = resId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof PackageDrawableIcon)) return false;
+ final PackageDrawableIcon other = (PackageDrawableIcon) o;
+ return Objects.equals(other.mPackage, mPackage) && other.mResId == mResId;
+ }
+
+ @Override
+ public Drawable getDrawable(Context context) {
+ try {
+ return context.createPackageContext(mPackage, 0).getDrawable(mResId);
+ } catch (Throwable t) {
+ Log.w(TAG, "Error loading package drawable pkg=" + mPackage + " id=" + mResId, t);
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("PackageDrawableIcon[pkg=%s,id=0x%08x]", mPackage, mResId);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index d1dc5d2b00e7c..81741ce8a8ac3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -67,12 +67,12 @@ public class LocationTile extends QSTile {
state.visible = !mKeyguard.isShowing();
state.value = locationEnabled;
if (locationEnabled) {
- state.iconId = R.drawable.ic_qs_location_on;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_location_on);
state.label = mContext.getString(R.string.quick_settings_location_label);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_location_on);
} else {
- state.iconId = R.drawable.ic_qs_location_off;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_location_off);
state.label = mContext.getString(R.string.quick_settings_location_label);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_location_off);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index ae40a4d03899f..49cd14afc944c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -17,7 +17,6 @@
package com.android.systemui.qs.tiles;
import android.content.res.Configuration;
-import android.content.res.Resources;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
@@ -26,6 +25,15 @@ import com.android.systemui.statusbar.policy.RotationLockController.RotationLock
/** Quick settings tile: Rotation **/
public class RotationLockTile extends QSTile {
+ private final AnimationIcon PORTRAIT_TO_AUTO
+ = new AnimationIcon(R.drawable.ic_portrait_to_auto_rotate_animation);
+ private final AnimationIcon AUTO_TO_PORTRAIT
+ = new AnimationIcon(R.drawable.ic_portrait_from_auto_rotate_animation);
+
+ private final AnimationIcon LANDSCAPE_TO_AUTO
+ = new AnimationIcon(R.drawable.ic_landscape_to_auto_rotate_animation);
+ private final AnimationIcon AUTO_TO_LANDSCAPE
+ = new AnimationIcon(R.drawable.ic_landscape_from_auto_rotate_animation);
private final RotationLockController mController;
@@ -51,30 +59,34 @@ public class RotationLockTile extends QSTile {
@Override
protected void handleClick() {
if (mController == null) return;
- mController.setRotationLocked(!mState.value);
+ final boolean newState = !mState.value;
+ mController.setRotationLocked(newState);
+ refreshState(newState ? UserBoolean.USER_TRUE : UserBoolean.USER_FALSE);
}
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
if (mController == null) return;
- final boolean rotationLocked = mController.isRotationLocked();
+ final boolean rotationLocked = arg != null ? ((UserBoolean) arg).value
+ : mController.isRotationLocked();
+ final boolean userInitiated = arg != null ? ((UserBoolean) arg).userInitiated : false;
state.visible = mController.isRotationLockAffordanceVisible();
- final Resources res = mContext.getResources();
state.value = rotationLocked;
+ final boolean portrait = mContext.getResources().getConfiguration().orientation
+ != Configuration.ORIENTATION_LANDSCAPE;
+ final AnimationIcon icon;
if (rotationLocked) {
- final boolean portrait = res.getConfiguration().orientation
- != Configuration.ORIENTATION_LANDSCAPE;
final int label = portrait ? R.string.quick_settings_rotation_locked_portrait_label
: R.string.quick_settings_rotation_locked_landscape_label;
- final int icon = portrait ? R.drawable.ic_qs_rotation_portrait
- : R.drawable.ic_qs_rotation_landscape;
state.label = mContext.getString(label);
- state.icon = mContext.getDrawable(icon);
+ icon = portrait ? AUTO_TO_PORTRAIT : AUTO_TO_LANDSCAPE;
} else {
state.label = mContext.getString(R.string.quick_settings_rotation_unlocked_label);
- state.icon = res.getDrawable(R.drawable.ic_qs_rotation_unlocked);
+ icon = portrait ? PORTRAIT_TO_AUTO : LANDSCAPE_TO_AUTO;
}
- state.contentDescription = getAccessibilityString(
+ icon.setAllowAnimation(userInitiated);
+ state.icon = icon;
+ state.contentDescription = getAccessibilityString(rotationLocked,
R.string.accessibility_rotation_lock_on_portrait,
R.string.accessibility_rotation_lock_on_landscape,
R.string.accessibility_rotation_lock_off);
@@ -83,14 +95,16 @@ public class RotationLockTile extends QSTile {
/**
* Get the correct accessibility string based on the state
*
+ * @param locked Whether or not rotation is locked.
* @param idWhenPortrait The id which should be used when locked in portrait.
* @param idWhenLandscape The id which should be used when locked in landscape.
* @param idWhenOff The id which should be used when the rotation lock is off.
* @return
*/
- private String getAccessibilityString(int idWhenPortrait, int idWhenLandscape, int idWhenOff) {
+ private String getAccessibilityString(boolean locked, int idWhenPortrait, int idWhenLandscape,
+ int idWhenOff) {
int stringID;
- if (mState.value) {
+ if (locked) {
final boolean portrait = mContext.getResources().getConfiguration().orientation
!= Configuration.ORIENTATION_LANDSCAPE;
stringID = portrait ? idWhenPortrait: idWhenLandscape;
@@ -102,7 +116,7 @@ public class RotationLockTile extends QSTile {
@Override
protected String composeChangeAnnouncement() {
- return getAccessibilityString(
+ return getAccessibilityString(mState.value,
R.string.accessibility_rotation_lock_on_portrait_changed,
R.string.accessibility_rotation_lock_on_landscape_changed,
R.string.accessibility_rotation_lock_off_changed);
@@ -111,7 +125,8 @@ public class RotationLockTile extends QSTile {
private final RotationLockControllerCallback mCallback = new RotationLockControllerCallback() {
@Override
public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
- refreshState();
+ refreshState(rotationLocked ? UserBoolean.BACKGROUND_TRUE
+ : UserBoolean.BACKGROUND_FALSE);
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 20c4ee8c406f2..7aa884effe7ab 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -120,19 +120,19 @@ public class WifiTile extends QSTile {
final String signalContentDescription;
final Resources r = mContext.getResources();
if (!state.enabled) {
- state.iconId = R.drawable.ic_qs_wifi_disabled;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disabled);
state.label = r.getString(R.string.quick_settings_wifi_label);
signalContentDescription = r.getString(R.string.accessibility_wifi_off);
} else if (wifiConnected) {
- state.iconId = cb.wifiSignalIconId;
+ state.icon = ResourceIcon.get(cb.wifiSignalIconId);
state.label = removeDoubleQuotes(cb.enabledDesc);
signalContentDescription = cb.wifiSignalContentDescription;
} else if (wifiNotConnected) {
- state.iconId = R.drawable.ic_qs_wifi_0;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_0);
state.label = r.getString(R.string.quick_settings_wifi_label);
signalContentDescription = r.getString(R.string.accessibility_no_wifi);
} else {
- state.iconId = R.drawable.ic_qs_wifi_no_network;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_no_network);
state.label = r.getString(R.string.quick_settings_wifi_label);
signalContentDescription = r.getString(R.string.accessibility_wifi_off);
}